diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index 001905b..0000000 --- a/.coveralls.yml +++ /dev/null @@ -1,4 +0,0 @@ -# https://github.com/php-coveralls/php-coveralls -service_name: travis-ci -coverage_clover: tests/logs/clover.xml -json_path: tests/logs/coveralls-upload.json diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index f3526ac..0000000 --- a/.gitattributes +++ /dev/null @@ -1,9 +0,0 @@ -/docs export-ignore -/tests export-ignore -/.github export-ignore -/.gitattributes export-ignore -/.coveralls.yml export-ignore -/.php_cs.dist export-ignore -/.gitignore export-ignore -/.travis.yml export-ignore -/phpunit.xml export-ignore diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml new file mode 100644 index 0000000..3687af0 --- /dev/null +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -0,0 +1,24 @@ +name: Fix PHP code style issues + +on: + push: + paths: + - '**.php' + +jobs: + php-code-styling: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + + - name: Fix PHP code style issues + uses: aglipanci/laravel-pint-action@2.3.0 + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Fix styling diff --git a/.github/workflows/pest-tests.yml b/.github/workflows/pest-tests.yml new file mode 100644 index 0000000..21e7d8f --- /dev/null +++ b/.github/workflows/pest-tests.yml @@ -0,0 +1,45 @@ +name: Pest Tests + +on: + workflow_dispatch: + push: + paths: + - "**.php" + - "composer.lock" + pull_request: + paths: + - "**.php" + - "composer.lock" + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + tools: composer:v2 + coverage: xdebug + + - name: Cache composer dependencies + uses: actions/cache@v4 + with: + path: vendor + key: composer-${{ hashFiles('composer.lock') }} + + - name: Install + run: composer kirby + + - name: Test & publish code coverage + uses: paambaati/codeclimate-action@v8.0.0 + with: + coverageCommand: vendor/bin/pest --ci + coverageLocations: ${{github.workspace}}/tests/clover.xml:clover + env: + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} + diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..e622628 --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,34 @@ +name: PHPStan + +on: + push: + paths: + - '**.php' + - 'phpstan.neon.dist' + +jobs: + phpstan: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + tools: composer:v2 + coverage: none + + - name: Cache composer dependencies + uses: actions/cache@v4 + with: + path: vendor + key: composer-${{ hashFiles('composer.lock') }} + + - name: Install + run: composer kirby + + - name: Run PHPStan + run: vendor/bin/phpstan --error-format=github diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 06de5c1..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Unit Tests - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - schedule: - - cron: '0 2 * * *' # run at 2 AM UTC - -jobs: - test: - runs-on: ubuntu-latest - name: Tests - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.1' - tools: composer - - - name: Install - run: composer install - - # update kirby to latest release of version 3 (includes release candidates!) - # https://semver.mwl.be/#!?package=getkirby%2Fcms&version=3.*&minimum-stability=RC - - name: Update Kirby Core - run: composer require getkirby/cms:"4.*@RC" - - - name: Run Tests - run: composer test diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php deleted file mode 100644 index bd4c20f..0000000 --- a/.php-cs-fixer.dist.php +++ /dev/null @@ -1,19 +0,0 @@ -exclude('content') - ->exclude('kirby') - ->exclude('node_modules') - //->exclude('site/plugins') - ->exclude('src') - ->exclude('vendor') - ->in(__DIR__) -; - -return (new PhpCsFixer\Config()) - ->setRules([ - '@PSR12' => true, - ]) - ->setFinder($finder) - ; diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 41f92e0..0000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: php -php: 8.1 -matrix: - fast_finish: true -install: composer install --no-interaction -script: composer test -after_success: travis_retry php vendor/bin/php-coveralls -v -notifications: - webhooks: - on_success: change - on_failure: always - on_start: never - urls: - - https://webhooks.gitter.im/e/77d9949056dc0462d25d diff --git a/classes/SecurityHeaders.php b/classes/SecurityHeaders.php index b440aac..e2aa9da 100644 --- a/classes/SecurityHeaders.php +++ b/classes/SecurityHeaders.php @@ -4,113 +4,170 @@ namespace Bnomei; +use Closure; use Kirby\Data\Json; use Kirby\Data\Yaml; -use Kirby\Toolkit\A; use Kirby\Filesystem\F; use Kirby\Filesystem\Mime; +use Kirby\Toolkit\A; use ParagonIE\CSPBuilder\CSPBuilder; + use function header; -final class SecurityHeaders +class SecurityHeaders { - /* - * @var array - */ - private $options; + const HEADERS_DEFAULT = [ + 'X-Powered-By' => '', // unset + 'X-Frame-Options' => 'DENY', + 'X-XSS-Protection' => '1; mode=block', + 'X-Content-Type-Options' => 'nosniff', + 'strict-transport-security' => 'max-age=31536000; includeSubdomains; preload', + 'Referrer-Policy' => 'no-referrer-when-downgrade', + 'Permissions-Policy' => 'interest-cohort=()', // flock-off + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy + 'Feature-Policy' => [ + "accelerometer 'none'", + "ambient-light-sensor 'none'", + "autoplay 'none'", + "battery 'none'", + "camera 'none'", + "display-capture 'none'", + "document-domain 'none'", + "encrypted-media 'none'", + "execution-while-not-rendered 'none'", + "execution-while-out-of-viewport 'none'", + "fullscreen 'none'", + "geolocation 'none'", + "gyroscope 'none'", + "layout-animations 'none'", + "legacy-image-formats 'none'", + "magnetometer 'none'", + "microphone 'none'", + "midi 'none'", + "navigation-override 'none'", + "oversized-images 'none'", + "payment 'none'", + "picture-in-picture 'none'", + "publickey-credentials 'none'", + "sync-xhr 'none'", + "usb 'none'", + "wake-lock 'none'", + "xr-spatial-tracking 'none'", + ], + ]; + + const LOADER_DEFAULT = [ + 'report-only' => false, + 'base-uri' => [ + 'self' => true, + ], + 'default-src' => [ + 'self' => true, + ], + 'connect-src' => [ + 'self' => true, + ], + 'font-src' => [ + 'self' => true, + ], + 'form-action' => [ + 'allow' => [], + 'self' => true, + ], + 'frame-ancestors' => [], + 'frame-src' => [ + 'allow' => [], + 'self' => false, + ], + 'img-src' => [ + 'self' => true, + 'data' => true, + ], + 'media-src' => [], + 'object-src' => [], + 'plugin-types' => [], + 'script-src' => [ + 'allow' => [], + 'hashes' => [], + 'self' => true, + 'unsafe-inline' => false, + 'unsafe-eval' => false, + ], + 'style-src' => [ + 'self' => true, + ], + 'upgrade-insecure-requests' => true, + 'worker-src' => [ + 'allow' => [], + 'self' => false, + ], + ]; + + private array $options; - /* - * @var ParagonIE\CSPBuilder\CSPBuilder - */ - private $cspBuilder; + private CSPBuilder $cspBuilder; - /* - * @var array - */ - private $nonces; + private array $nonces = []; public function __construct(array $options = []) { - $isPanel = strpos( - kirby()->request()->url()->toString(), - kirby()->urls()->panel() - ) !== false; - $isApi = strpos( - kirby()->request()->url()->toString(), - kirby()->urls()->api() - ) !== false; - $panelHasNonces = method_exists(kirby(), 'nonce'); - - $enabled = !kirby()->system()->isLocal(); - if ($isPanel || $isApi) { - $enabled = false; - } + $url = kirby()->request()->url()->toString(); + $isPanel = str_contains($url, kirby()->urls()->panel()); + $isApi = str_contains($url, kirby()->urls()->api()); + $enabled = ! kirby()->system()->isLocal() && ! $isPanel && ! $isApi; - $defaults = [ + $this->options = array_merge([ 'debug' => option('debug'), 'enabled' => option('bnomei.securityheaders.enabled', $enabled), - 'headers' => option('bnomei.securityheaders.headers'), - 'seed' => option('bnomei.securityheaders.seed'), 'panel' => $isPanel, - 'panelnonces' => $panelHasNonces ? ['panel' => kirby()->nonce()] : [], + 'panelnonces' => ['panel' => kirby()->nonce()], + 'seed' => option('bnomei.securityheaders.seed'), + 'headers' => option('bnomei.securityheaders.headers'), 'loader' => option('bnomei.securityheaders.loader'), 'setter' => option('bnomei.securityheaders.setter'), - ]; - $this->options = array_merge($defaults, $options); - $this->nonces = []; + ], $options); foreach ($this->options as $key => $call) { - if (is_callable($call) && in_array($key, ['loader', 'enabled', 'headers', 'seed'])) { + if ($call instanceof Closure && in_array($key, ['loader', 'enabled', 'headers', 'seed'])) { $this->options[$key] = $call(); } } + + $this->load(); + $this->applySetter(); } - /** - * @return array|misc - */ - public function option(?string $key = null) + public function option(?string $key = null): mixed { if ($key) { return A::get($this->options, $key); } + return $this->options; } - /** - * @return string|null - */ public function getNonce(string $key): ?string { return A::get($this->nonces, $key); } - /** - * @param string - */ public function setNonce(string $key): string { - $nonceArr = [$key, time(), filemtime(__FILE__), kirby()->roots()->assets()]; + $nonceArr = [$key, time(), filemtime(__FILE__), (string) kirby()->roots()->index()]; shuffle($nonceArr); $nonce = base64_encode(sha1(implode('', $nonceArr))); $this->nonces[$key] = $nonce; + return $nonce; } - /** - * @return mixed - */ - public function csp() + public function csp(): CSPBuilder { return $this->cspBuilder; } - /** - * @param null $data - * @return CSPBuilder - */ - public function load($data = null): CSPBuilder + public function load(array|string|null $data = null): CSPBuilder { if (is_null($data)) { $data = $this->option('loader'); @@ -125,23 +182,27 @@ public function load($data = null): CSPBuilder $data = Yaml::decode($data); } } + if (is_array($data)) { $this->cspBuilder = CSPBuilder::fromArray($data); - } else { - $this->cspBuilder = new CSPBuilder(); + } else { // aka null + $this->cspBuilder = new CSPBuilder; } // add nonce for self - if ($self = $this->option('seed')) { - $nonce = $this->setNonce((string) $self); + if ($seed = strval($this->option('seed'))) { + $nonce = $this->setNonce($seed); $this->cspBuilder->nonce('script-src', $nonce); $this->cspBuilder->nonce('style-src', $nonce); } // add panel nonces if ($this->option('panel')) { - $panelnonces = $this->option('panelnonces'); + $panelnonces = (array) $this->option('panelnonces'); foreach ($panelnonces as $nonce) { + if (! is_string($nonce)) { + continue; + } $this->cspBuilder->nonce('img-src', $nonce); $this->cspBuilder->nonce('script-src', $nonce); $this->cspBuilder->nonce('style-src', $nonce); @@ -151,84 +212,53 @@ public function load($data = null): CSPBuilder return $this->cspBuilder; } - /** - * - */ - public function applySetter() + public function applySetter(): void { - // additional setters $csp = $this->option('setter'); - if (is_callable($csp)) { + if ($csp instanceof Closure) { $csp($this); } } - /** - * @return bool - */ public function sendHeaders(): bool { if ($this->option('enabled') === false) { return false; } - if ($this->option('debug') && $this->option('enabled') !== 'force') { - return false; - } - // from config - $headers = $this->option('headers'); + $headers = (array) $this->option('headers'); foreach ($headers as $key => $value) { $value = is_array($value) ? implode('; ', $value) : $value; - header($key . ': ' . $value); + header(strval($key).': '.strval($value)); } - // from cspbuilder - if ($this->cspBuilder) { - $this->cspBuilder->sendCSPHeader(); - } - return true; + return $this->cspBuilder->sendCSPHeader(); } - /** - * @param string $filepath - * @return bool - */ public function saveApache(string $filepath): bool { $this->cspBuilder->saveSnippet($filepath, CSPBuilder::FORMAT_APACHE); + return F::exists($filepath); } - /** - * @param string $filepath - * @return bool - */ public function saveNginx(string $filepath): bool { $this->cspBuilder->saveSnippet($filepath, CSPBuilder::FORMAT_NGINX); + return F::exists($filepath); } - /* - * @var SecurityHeaders - */ - private static $singleton; + private static ?SecurityHeaders $singleton = null; - /** - * @param array $options - * @return SecurityHeaders - * @codeCoverageIgnore - */ public static function singleton(array $options = []): SecurityHeaders { - if (self::$singleton) { + if (self::$singleton !== null) { return self::$singleton; } $sec = new SecurityHeaders($options); - $sec->load(); - $sec->applySetter(); self::$singleton = $sec; return self::$singleton; diff --git a/composer.json b/composer.json index 3d8e7f5..751c92c 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "bnomei/kirby3-security-headers", "type": "kirby-plugin", - "version": "4.0.0", + "version": "5.0.0", "license": "MIT", "description": "Kirby Plugin for easier Security Headers setup", "authors": [ @@ -34,28 +34,28 @@ "optimize-autoloader": true, "sort-packages": true, "allow-plugins": { - "getkirby/composer-installer": true + "getkirby/composer-installer": true, + "pestphp/pest-plugin": true } }, "require": { - "php": ">=8.1.0", + "php": ">=8.2.0", "getkirby/composer-installer": "^1.2", - "paragonie/csp-builder": "^2.5" + "paragonie/csp-builder": "^3.0" }, "require-dev": { - "getkirby/cms": "^4.0", - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^9.5" + "getkirby/cms": "^5.0.0-alpha.4", + "larastan/larastan": "^v3.0.0", + "laravel/pint": "^1.13", + "pestphp/pest": "^v3.5.1", + "spatie/ray": "^1.39" }, "scripts": { - "analyze": "phpstan analyse classes", - "fix": "php-cs-fixer fix", - "test": [ - "mkdir -p tests/logs", - "@putenv XDEBUG_MODE=coverage", - "phpunit --configuration ./phpunit.xml" - ], + "stan": "./vendor/bin/phpstan", + "fix": "./vendor/bin/pint", + "test": "./vendor/bin/pest --profile", "dist": [ + "composer fix", "composer install --no-dev --optimize-autoloader", "git rm -rf --cached .; git add .;" ], @@ -63,7 +63,9 @@ "composer install", "composer update", "composer install --working-dir=tests/kirby --no-dev --optimize-autoloader", - "composer update --working-dir=tests/kirby" + "composer update --working-dir=tests/kirby", + "sed -i.bak 's/function dump(/function xdump(/g' tests/kirby/config/helpers.php", + "sed -i.bak 's/function e(/function xe(/g' tests/kirby/config/helpers.php" ] }, "extra": { diff --git a/composer.lock b/composer.lock index c980b3f..9f5fa98 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18addf989686478ebf461db052d40419", + "content-hash": "137ea556a6733e83dd49c3d70017ef0a", "packages": [ { "name": "getkirby/composer-installer", @@ -53,18 +53,208 @@ ], "time": "2020-12-28T12:54:39+00:00" }, + { + "name": "opis/json-schema", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/opis/json-schema.git", + "reference": "c48df6d7089a45f01e1c82432348f2d5976f9bfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/json-schema/zipball/c48df6d7089a45f01e1c82432348f2d5976f9bfb", + "reference": "c48df6d7089a45f01e1c82432348f2d5976f9bfb", + "shasum": "" + }, + "require": { + "ext-json": "*", + "opis/string": "^2.0", + "opis/uri": "^1.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "ext-bcmath": "*", + "ext-intl": "*", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\JsonSchema\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + }, + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + } + ], + "description": "Json Schema Validator for PHP", + "homepage": "https://opis.io/json-schema", + "keywords": [ + "json", + "json-schema", + "schema", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/opis/json-schema/issues", + "source": "https://github.com/opis/json-schema/tree/2.3.0" + }, + "time": "2022-01-08T20:38:03+00:00" + }, + { + "name": "opis/string", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/opis/string.git", + "reference": "9ebf1a1f873f502f6859d11210b25a4bf5d141e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/string/zipball/9ebf1a1f873f502f6859d11210b25a4bf5d141e7", + "reference": "9ebf1a1f873f502f6859d11210b25a4bf5d141e7", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\String\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "Multibyte strings as objects", + "homepage": "https://opis.io/string", + "keywords": [ + "multi-byte", + "opis", + "string", + "string manipulation", + "utf-8" + ], + "support": { + "issues": "https://github.com/opis/string/issues", + "source": "https://github.com/opis/string/tree/2.0.1" + }, + "time": "2022-01-14T15:42:23+00:00" + }, + { + "name": "opis/uri", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/opis/uri.git", + "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/uri/zipball/0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a", + "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a", + "shasum": "" + }, + "require": { + "opis/string": "^2.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\Uri\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "Build, parse and validate URIs and URI-templates", + "homepage": "https://opis.io", + "keywords": [ + "URI Template", + "parse url", + "punycode", + "uri", + "uri components", + "url", + "validate uri" + ], + "support": { + "issues": "https://github.com/opis/uri/issues", + "source": "https://github.com/opis/uri/tree/1.1.0" + }, + "time": "2021-05-22T15:57:08+00:00" + }, { "name": "paragonie/constant_time_encoding", - "version": "v2.6.3", + "version": "v2.7.0", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "58c3f47f650c94ec05a151692652a868995d2938" + "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", - "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/52a0d99e69f56b9ec27ace92ba56897fe6993105", + "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105", "shasum": "" }, "require": { @@ -118,26 +308,27 @@ "issues": "https://github.com/paragonie/constant_time_encoding/issues", "source": "https://github.com/paragonie/constant_time_encoding" }, - "time": "2022-06-14T06:56:20+00:00" + "time": "2024-05-08T12:18:48+00:00" }, { "name": "paragonie/csp-builder", - "version": "v2.9.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/paragonie/csp-builder.git", - "reference": "0c9592c3862eb8c6effcc0d31c7e4d8bbc0b3bae" + "reference": "e2f9f177dd33311b7c16ea206488e0b10d1ea4d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/csp-builder/zipball/0c9592c3862eb8c6effcc0d31c7e4d8bbc0b3bae", - "reference": "0c9592c3862eb8c6effcc0d31c7e4d8bbc0b3bae", + "url": "https://api.github.com/repos/paragonie/csp-builder/zipball/e2f9f177dd33311b7c16ea206488e0b10d1ea4d3", + "reference": "e2f9f177dd33311b7c16ea206488e0b10d1ea4d3", "shasum": "" }, "require": { "ext-json": "*", + "opis/json-schema": "^2.3", "paragonie/constant_time_encoding": "^2", - "php": "^7.1|^8", + "php": "^7.4|^8", "psr/http-message": "^1|^2" }, "require-dev": { @@ -177,7 +368,7 @@ "issues": "https://github.com/paragonie/csp-builder/issues", "source": "https://github.com/paragonie/csp-builder" }, - "time": "2023-05-24T14:47:37+00:00" + "time": "2024-05-08T13:05:32+00:00" }, { "name": "psr/http-message", @@ -234,6 +425,228 @@ } ], "packages-dev": [ + { + "name": "brianium/paratest", + "version": "v7.6.0", + "source": { + "type": "git", + "url": "https://github.com/paratestphp/paratest.git", + "reference": "68ff89a8de47d086588e391a516d2a5b5fde6254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/68ff89a8de47d086588e391a516d2a5b5fde6254", + "reference": "68ff89a8de47d086588e391a516d2a5b5fde6254", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-simplexml": "*", + "fidry/cpu-core-counter": "^1.2.0", + "jean85/pretty-package-versions": "^2.0.6", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "phpunit/php-code-coverage": "^11.0.7", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-timer": "^7.0.1", + "phpunit/phpunit": "^11.4.1", + "sebastian/environment": "^7.2.0", + "symfony/console": "^6.4.11 || ^7.1.5", + "symfony/process": "^6.4.8 || ^7.1.5" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0.0", + "ext-pcov": "*", + "ext-posix": "*", + "phpstan/phpstan": "^1.12.6", + "phpstan/phpstan-deprecation-rules": "^1.2.1", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.1", + "squizlabs/php_codesniffer": "^3.10.3", + "symfony/filesystem": "^6.4.9 || ^7.1.5" + }, + "bin": [ + "bin/paratest", + "bin/paratest_for_phpstorm" + ], + "type": "library", + "autoload": { + "psr-4": { + "ParaTest\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" + }, + { + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" + } + ], + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", + "keywords": [ + "concurrent", + "parallel", + "phpunit", + "testing" + ], + "support": { + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v7.6.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/Slamdunk", + "type": "github" + }, + { + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" + } + ], + "time": "2024-10-15T12:38:31+00:00" + }, + { + "name": "brick/math", + "version": "0.12.1", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "f510c0a40911935b77b86859eb5223d58d660df1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1", + "reference": "f510c0a40911935b77b86859eb5223d58d660df1", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^10.1", + "vimeo/psalm": "5.16.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "bignumber", + "brick", + "decimal", + "integer", + "math", + "mathematics", + "rational" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.12.1" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2023-11-29T23:19:16+00:00" + }, + { + "name": "carbonphp/carbon-doctrine-types", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/dbal": "<4.0.0 || >=5.0.0" + }, + "require-dev": { + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2024-02-09T16:56:22+00:00" + }, { "name": "christian-riesen/base32", "version": "1.6.0", @@ -295,16 +708,16 @@ }, { "name": "claviska/simpleimage", - "version": "4.0.6", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/claviska/SimpleImage.git", - "reference": "969de5e61810ef91f6f83c475b192c4841367dfa" + "reference": "dfbe53c01dae8467468ef2b817c09b786a7839d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/claviska/SimpleImage/zipball/969de5e61810ef91f6f83c475b192c4841367dfa", - "reference": "969de5e61810ef91f6f83c475b192c4841367dfa", + "url": "https://api.github.com/repos/claviska/SimpleImage/zipball/dfbe53c01dae8467468ef2b817c09b786a7839d2", + "reference": "dfbe53c01dae8467468ef2b817c09b786a7839d2", "shasum": "" }, "require": { @@ -336,7 +749,7 @@ "description": "A PHP class that makes working with images as simple as possible.", "support": { "issues": "https://github.com/claviska/SimpleImage/issues", - "source": "https://github.com/claviska/SimpleImage/tree/4.0.6" + "source": "https://github.com/claviska/SimpleImage/tree/4.2.0" }, "funding": [ { @@ -344,28 +757,28 @@ "type": "github" } ], - "time": "2023-07-27T16:48:12+00:00" + "time": "2024-04-15T16:07:16+00:00" }, { "name": "composer/semver", - "version": "3.4.0", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { @@ -409,7 +822,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" + "source": "https://github.com/composer/semver/tree/3.4.3" }, "funding": [ { @@ -425,65 +838,133 @@ "type": "tidelift" } ], - "time": "2023-08-31T09:50:34+00:00" + "time": "2024-09-19T14:15:21+00:00" }, { - "name": "doctrine/instantiator", - "version": "2.0.0", + "name": "doctrine/deprecations", + "version": "1.1.3", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^11", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5.27", - "vimeo/psalm": "^5.4" + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", + "time": "2024-01-30T19:34:25+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^11.0", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.10" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { @@ -491,34 +972,95 @@ "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", "type": "tidelift" } ], - "time": "2022-12-30T00:23:10+00:00" + "time": "2024-02-18T20:23:39+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" }, { "name": "filp/whoops", - "version": "2.15.4", + "version": "2.16.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546" + "reference": "befcdc0e5dce67252aa6322d82424be928214fa2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546", - "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546", + "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2", + "reference": "befcdc0e5dce67252aa6322d82424be928214fa2", "shasum": "" }, "require": { - "php": "^5.5.9 || ^7.0 || ^8.0", + "php": "^7.1 || ^8.0", "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "require-dev": { - "mockery/mockery": "^0.9 || ^1.0", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" }, "suggest": { "symfony/var-dumper": "Pretty print complex values better with var-dumper available", @@ -558,7 +1100,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.15.4" + "source": "https://github.com/filp/whoops/tree/2.16.0" }, "funding": [ { @@ -566,26 +1108,97 @@ "type": "github" } ], - "time": "2023-11-03T12:00:00+00:00" + "time": "2024-09-25T12:00:00+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6|^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2023-10-12T05:21:21+00:00" }, { "name": "getkirby/cms", - "version": "4.1.1", + "version": "5.0.0-alpha.4", "source": { "type": "git", "url": "https://github.com/getkirby/kirby.git", - "reference": "1353c9fbe3ede6bee946f527d146841719eef7d5" + "reference": "6adc851f1bd7de37933185594622bcc526f518d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getkirby/kirby/zipball/1353c9fbe3ede6bee946f527d146841719eef7d5", - "reference": "1353c9fbe3ede6bee946f527d146841719eef7d5", + "url": "https://api.github.com/repos/getkirby/kirby/zipball/6adc851f1bd7de37933185594622bcc526f518d4", + "reference": "6adc851f1bd7de37933185594622bcc526f518d4", "shasum": "" }, "require": { "christian-riesen/base32": "1.6.0", - "claviska/simpleimage": "4.0.6", - "composer/semver": "3.4.0", + "claviska/simpleimage": "4.2.0", + "composer/semver": "3.4.3", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -597,15 +1210,15 @@ "ext-mbstring": "*", "ext-openssl": "*", "ext-simplexml": "*", - "filp/whoops": "2.15.4", + "filp/whoops": "2.16.0", "getkirby/composer-installer": "^1.2.1", - "laminas/laminas-escaper": "2.13.0", + "laminas/laminas-escaper": "2.14.0", "michelf/php-smartypants": "1.8.1", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "phpmailer/phpmailer": "6.9.1", - "symfony/polyfill-intl-idn": "1.28.0", - "symfony/polyfill-mbstring": "1.28.0", - "symfony/yaml": "6.4.0" + "php": "~8.2.0 || ~8.3.0", + "phpmailer/phpmailer": "6.9.2", + "symfony/polyfill-intl-idn": "1.31.0", + "symfony/polyfill-mbstring": "1.31.0", + "symfony/yaml": "7.1.6" }, "replace": { "symfony/polyfill-php72": "*" @@ -617,6 +1230,7 @@ "ext-fileinfo": "Improved mime type detection for files", "ext-intl": "Improved i18n number formatting", "ext-memcached": "Support for the Memcached cache driver", + "ext-redis": "Support for the Redis cache driver", "ext-sodium": "Support for the crypto class and more robust session handling", "ext-zip": "Support for ZIP archive file functions", "ext-zlib": "Sanitization and validation for svgz files" @@ -669,26 +1283,26 @@ "type": "custom" } ], - "time": "2024-02-26T10:06:07+00:00" + "time": "2024-11-20T16:09:49+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.8.1", + "version": "7.9.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.1", - "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -699,9 +1313,9 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -779,7 +1393,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" }, "funding": [ { @@ -795,20 +1409,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:35:24+00:00" + "time": "2024-07-24T11:22:20+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.0.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", "shasum": "" }, "require": { @@ -816,7 +1430,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "type": "library", "extra": { @@ -862,7 +1476,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.2" + "source": "https://github.com/guzzle/promises/tree/2.0.4" }, "funding": [ { @@ -878,20 +1492,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:19:20+00:00" + "time": "2024-10-17T10:06:22+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.6.2", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", "shasum": "" }, "require": { @@ -906,8 +1520,8 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -978,7 +1592,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.6.2" + "source": "https://github.com/guzzle/psr7/tree/2.7.0" }, "funding": [ { @@ -994,102 +1608,127 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:05:35+00:00" + "time": "2024-07-18T11:15:46+00:00" }, { - "name": "laminas/laminas-escaper", - "version": "2.13.0", + "name": "guzzlehttp/uri-template", + "version": "v1.0.3", "source": { "type": "git", - "url": "https://github.com/laminas/laminas-escaper.git", - "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba" + "url": "https://github.com/guzzle/uri-template.git", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/af459883f4018d0f8a0c69c7a209daef3bf973ba", - "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-mbstring": "*", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-escaper": "*" + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" }, "require-dev": { - "infection/infection": "^0.27.0", - "laminas/laminas-coding-standard": "~2.5.0", - "maglnet/composer-require-checker": "^3.8.0", - "phpunit/phpunit": "^9.6.7", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.9" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "uri-template/tests": "1.0.0" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { "psr-4": { - "Laminas\\Escaper\\": "src/" + "GuzzleHttp\\UriTemplate\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", - "homepage": "https://laminas.dev", + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "description": "A polyfill class for uri_template of PHP", "keywords": [ - "escaper", - "laminas" + "guzzlehttp", + "uri-template" ], "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-escaper/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-escaper/issues", - "rss": "https://github.com/laminas/laminas-escaper/releases.atom", - "source": "https://github.com/laminas/laminas-escaper" + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.3" }, "funding": [ { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" } ], - "time": "2023-10-10T08:35:13+00:00" + "time": "2023-12-03T19:50:20+00:00" }, { - "name": "league/color-extractor", - "version": "0.4.0", + "name": "illuminate/bus", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/thephpleague/color-extractor.git", - "reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505" + "url": "https://github.com/illuminate/bus.git", + "reference": "c5987e61eca1f9b1eef2caafd4ab370625a4b10a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/21fcac6249c5ef7d00eb83e128743ee6678fe505", - "reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505", + "url": "https://api.github.com/repos/illuminate/bus/zipball/c5987e61eca1f9b1eef2caafd4ab370625a4b10a", + "reference": "c5987e61eca1f9b1eef2caafd4ab370625a4b10a", "shasum": "" }, "require": { - "ext-gd": "*", - "php": "^7.3 || ^8.0" - }, - "replace": { - "matthecat/colorextractor": "*" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2", - "phpunit/phpunit": "^9.5" + "illuminate/collections": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/pipeline": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2" }, "suggest": { - "ext-curl": "To download images from remote URLs if allow_url_fopen is disabled for security reasons" + "illuminate/queue": "Required to use closures when chaining jobs (^7.0)." }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, "autoload": { "psr-4": { - "League\\ColorExtractor\\": "src" + "Illuminate\\Bus\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1098,348 +1737,327 @@ ], "authors": [ { - "name": "Mathieu Lechat", - "email": "math.lechat@gmail.com", - "homepage": "http://matthecat.com", - "role": "Developer" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Extract colors from an image as a human would do.", - "homepage": "https://github.com/thephpleague/color-extractor", - "keywords": [ - "color", - "extract", - "human", - "image", - "palette" - ], + "description": "The Illuminate Bus package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/thephpleague/color-extractor/issues", - "source": "https://github.com/thephpleague/color-extractor/tree/0.4.0" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "time": "2022-09-24T15:57:16+00:00" + "time": "2024-11-26T14:46:56+00:00" }, { - "name": "michelf/php-smartypants", - "version": "1.8.1", + "name": "illuminate/collections", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/michelf/php-smartypants.git", - "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad" + "url": "https://github.com/illuminate/collections.git", + "reference": "fd2103ddc121449a7926fc34a9d220e5b88183c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-smartypants/zipball/47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", - "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", + "url": "https://api.github.com/repos/illuminate/collections/zipball/fd2103ddc121449a7926fc34a9d220e5b88183c1", + "reference": "fd2103ddc121449a7926fc34a9d220e5b88183c1", "shasum": "" }, "require": { - "php": ">=5.3.0" + "illuminate/conditionable": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/macroable": "^11.0", + "php": "^8.2" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^7.0)." }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, "autoload": { - "psr-0": { - "Michelf": "" + "files": [ + "helpers.php" + ], + "psr-4": { + "Illuminate\\Support\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Michel Fortin", - "email": "michel.fortin@michelf.ca", - "homepage": "https://michelf.ca/", - "role": "Developer" - }, - { - "name": "John Gruber", - "homepage": "https://daringfireball.net/" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "PHP SmartyPants", - "homepage": "https://michelf.ca/projects/php-smartypants/", - "keywords": [ - "dashes", - "quotes", - "spaces", - "typographer", - "typography" - ], + "description": "The Illuminate Collections package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/michelf/php-smartypants/issues", - "source": "https://github.com/michelf/php-smartypants/tree/1.8.1" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "time": "2016-12-13T01:01:17+00:00" + "time": "2024-11-27T14:51:56+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.11.1", + "name": "illuminate/conditionable", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "url": "https://github.com/illuminate/conditionable.git", + "reference": "911df1bda950a3b799cf80671764e34eede131c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/911df1bda950a3b799cf80671764e34eede131c6", + "reference": "911df1bda950a3b799cf80671764e34eede131c6", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + "php": "^8.0.2" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], "psr-4": { - "DeepCopy\\": "src/DeepCopy/" + "Illuminate\\Support\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" - }, - "funding": [ + "authors": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "time": "2023-03-08T13:26:56+00:00" + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-11-21T16:28:56+00:00" }, { - "name": "nikic/php-parser", - "version": "v5.0.1", + "name": "illuminate/console", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69" + "url": "https://github.com/illuminate/console.git", + "reference": "294b597ee3eb8f690a921745c981c159f4e2b002" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2218c2252c874a4624ab2f613d86ac32d227bc69", - "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69", + "url": "https://api.github.com/repos/illuminate/console/zipball/294b597ee3eb8f690a921745c981c159f4e2b002", + "reference": "294b597ee3eb8f690a921745c981c159f4e2b002", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" + "ext-mbstring": "*", + "illuminate/collections": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/macroable": "^11.0", + "illuminate/support": "^11.0", + "illuminate/view": "^11.0", + "laravel/prompts": "^0.1.20|^0.2|^0.3", + "nunomaduro/termwind": "^2.0", + "php": "^8.2", + "symfony/console": "^7.0.3", + "symfony/polyfill-php83": "^1.31", + "symfony/process": "^7.0.3" }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "suggest": { + "dragonmantank/cron-expression": "Required to use scheduler (^3.3.2).", + "ext-pcntl": "Required to use signal trapping.", + "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^7.8).", + "illuminate/bus": "Required to use the scheduled job dispatcher (^11.0).", + "illuminate/container": "Required to use the scheduler (^11.0).", + "illuminate/filesystem": "Required to use the generator command (^11.0).", + "illuminate/queue": "Required to use closures for scheduled jobs (^11.0)." }, - "bin": [ - "bin/php-parse" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "11.x-dev" } }, "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "Illuminate\\Console\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], + "description": "The Illuminate Console package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.1" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "time": "2024-02-21T19:24:10+00:00" + "time": "2024-11-27T14:57:44+00:00" }, { - "name": "phar-io/manifest", - "version": "2.0.3", + "name": "illuminate/container", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "url": "https://github.com/illuminate/container.git", + "reference": "b057b0bbb38d7c7524df1ca5c38e7318f4c64d26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/illuminate/container/zipball/b057b0bbb38d7c7524df1ca5c38e7318f4c64d26", + "reference": "b057b0bbb38d7c7524df1ca5c38e7318f4c64d26", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" + "illuminate/contracts": "^11.0", + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1" + }, + "provide": { + "psr/container-implementation": "1.1|2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "11.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Illuminate\\Container\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "description": "The Illuminate Container package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "time": "2021-07-20T11:28:43+00:00" + "time": "2024-11-21T20:07:31+00:00" }, { - "name": "phar-io/version", - "version": "3.2.1", + "name": "illuminate/contracts", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + "url": "https://github.com/illuminate/contracts.git", + "reference": "184317f701ba20ca265e36808ed54b75b115972d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/184317f701ba20ca265e36808ed54b75b115972d", + "reference": "184317f701ba20ca265e36808ed54b75b115972d", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/simple-cache": "^1.0|^2.0|^3.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Illuminate\\Contracts\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Library for handling version information and constraints", + "description": "The Illuminate Contracts package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "time": "2022-02-21T01:04:05+00:00" + "time": "2024-11-25T15:33:38+00:00" }, { - "name": "php-coveralls/php-coveralls", - "version": "v2.7.0", + "name": "illuminate/database", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/php-coveralls/php-coveralls.git", - "reference": "b36fa4394e519dafaddc04ae03976bc65a25ba15" + "url": "https://github.com/illuminate/database.git", + "reference": "f08bb9ffa1d829cb6f8bb713e5c9cd3a47636ff2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/b36fa4394e519dafaddc04ae03976bc65a25ba15", - "reference": "b36fa4394e519dafaddc04ae03976bc65a25ba15", + "url": "https://api.github.com/repos/illuminate/database/zipball/f08bb9ffa1d829cb6f8bb713e5c9cd3a47636ff2", + "reference": "f08bb9ffa1d829cb6f8bb713e5c9cd3a47636ff2", "shasum": "" }, "require": { - "ext-json": "*", - "ext-simplexml": "*", - "guzzlehttp/guzzle": "^6.0 || ^7.0", - "php": "^7.0 || ^8.0", - "psr/log": "^1.0 || ^2.0", - "symfony/config": "^2.1 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/console": "^2.1 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/yaml": "^2.0.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0 || ^7.0 || >=8.0 <8.5.29 || >=9.0 <9.5.23", - "sanmai/phpunit-legacy-adapter": "^6.1 || ^8.0" + "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", + "ext-pdo": "*", + "illuminate/collections": "^11.0", + "illuminate/container": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/macroable": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2" }, "suggest": { - "symfony/http-kernel": "Allows Symfony integration" + "ext-filter": "Required to use the Postgres database driver.", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.24).", + "illuminate/console": "Required to use the database commands (^11.0).", + "illuminate/events": "Required to use the observers with Eloquent (^11.0).", + "illuminate/filesystem": "Required to use the migrations (^11.0).", + "illuminate/pagination": "Required to paginate the result set (^11.0).", + "laravel/serializable-closure": "Required to handle circular references in model serialization (^1.3).", + "symfony/finder": "Required to use Eloquent model factories (^7.0)." }, - "bin": [ - "bin/php-coveralls" - ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, "autoload": { "psr-4": { - "PhpCoveralls\\": "src/" + "Illuminate\\Database\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1448,571 +2066,468 @@ ], "authors": [ { - "name": "Kitamura Satoshi", - "email": "with.no.parachute@gmail.com", - "homepage": "https://www.facebook.com/satooshi.jp", - "role": "Original creator" - }, - { - "name": "Takashi Matsuo", - "email": "tmatsuo@google.com" - }, - { - "name": "Google Inc" - }, - { - "name": "Dariusz Ruminski", - "email": "dariusz.ruminski@gmail.com", - "homepage": "https://github.com/keradus" - }, - { - "name": "Contributors", - "homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "PHP client library for Coveralls API", - "homepage": "https://github.com/php-coveralls/php-coveralls", + "description": "The Illuminate Database package.", + "homepage": "https://laravel.com", "keywords": [ - "ci", - "coverage", - "github", - "test" + "database", + "laravel", + "orm", + "sql" ], "support": { - "issues": "https://github.com/php-coveralls/php-coveralls/issues", - "source": "https://github.com/php-coveralls/php-coveralls/tree/v2.7.0" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "time": "2023-11-22T10:21:01+00:00" + "time": "2024-11-25T22:44:52+00:00" }, { - "name": "phpmailer/phpmailer", - "version": "v6.9.1", + "name": "illuminate/events", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18" + "url": "https://github.com/illuminate/events.git", + "reference": "6903ea1c56786904e06c345108665aa0509f3d3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18", + "url": "https://api.github.com/repos/illuminate/events/zipball/6903ea1c56786904e06c345108665aa0509f3d3c", + "reference": "6903ea1c56786904e06c345108665aa0509f3d3c", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/annotations": "^1.2.6 || ^1.13.3", - "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.7.2", - "yoast/phpunit-polyfills": "^1.0.4" - }, - "suggest": { - "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "ext-openssl": "Needed for secure SMTP sending and DKIM signing", - "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", - "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" + "illuminate/bus": "^11.0", + "illuminate/collections": "^11.0", + "illuminate/container": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/macroable": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, "autoload": { + "files": [ + "functions.php" + ], "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" + "Illuminate\\Events\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-2.1-only" + "MIT" ], "authors": [ { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "description": "The Illuminate Events package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "time": "2023-11-25T22:23:28+00:00" + "time": "2024-11-25T22:44:52+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "9.2.30", + "name": "illuminate/filesystem", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" + "url": "https://github.com/illuminate/filesystem.git", + "reference": "ec19853eaa9e25bbf3e10cf880a3cd0b6a4b75c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", - "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "url": "https://api.github.com/repos/illuminate/filesystem/zipball/ec19853eaa9e25bbf3e10cf880a3cd0b6a4b75c4", + "reference": "ec19853eaa9e25bbf3e10cf880a3cd0b6a4b75c4", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "illuminate/collections": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/macroable": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2", + "symfony/finder": "^7.0.3" }, "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-hash": "Required to use the Filesystem class.", + "illuminate/http": "Required for handling uploaded files (^7.0).", + "league/flysystem": "Required to use the Flysystem local driver (^3.25.1).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", + "symfony/mime": "Required to enable support for guessing extensions (^7.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-master": "11.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "functions.php" + ], + "psr-4": { + "Illuminate\\Filesystem\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], + "description": "The Illuminate Filesystem package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-22T06:47:57+00:00" + "time": "2024-11-26T14:46:56+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "name": "illuminate/http", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "url": "https://github.com/illuminate/http.git", + "reference": "a572a50f70c292ae5f39b2d0cbcd39983e20816f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/illuminate/http/zipball/a572a50f70c292ae5f39b2d0cbcd39983e20816f", + "reference": "a572a50f70c292ae5f39b2d0cbcd39983e20816f", "shasum": "" }, "require": { - "php": ">=7.3" + "ext-filter": "*", + "fruitcake/php-cors": "^1.3", + "guzzlehttp/guzzle": "^7.8.2", + "guzzlehttp/uri-template": "^1.0", + "illuminate/collections": "^11.0", + "illuminate/macroable": "^11.0", + "illuminate/session": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2", + "symfony/http-foundation": "^7.0.3", + "symfony/http-kernel": "^7.0.3", + "symfony/mime": "^7.0.3", + "symfony/polyfill-php83": "^1.31" }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "suggest": { + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image()." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "11.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Illuminate\\Http\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], + "description": "The Illuminate Http package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2024-11-27T14:50:46+00:00" }, { - "name": "phpunit/php-invoker", - "version": "3.1.1", + "name": "illuminate/macroable", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "url": "https://github.com/illuminate/macroable.git", + "reference": "e1cb9e51b9ed5d3c9bc1ab431d0a52fe42a990ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/e1cb9e51b9ed5d3c9bc1ab431d0a52fe42a990ed", + "reference": "e1cb9e51b9ed5d3c9bc1ab431d0a52fe42a990ed", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" + "php": "^8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "11.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Illuminate\\Support\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], + "description": "The Illuminate Macroable package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2024-06-28T20:10:30+00:00" }, { - "name": "phpunit/php-text-template", - "version": "2.0.4", + "name": "illuminate/pipeline", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "url": "https://github.com/illuminate/pipeline.git", + "reference": "c643301f0bcf64a7e62569a73dc9c9841655bfb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/illuminate/pipeline/zipball/c643301f0bcf64a7e62569a73dc9c9841655bfb3", + "reference": "c643301f0bcf64a7e62569a73dc9c9841655bfb3", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "illuminate/contracts": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "11.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Illuminate\\Pipeline\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], + "description": "The Illuminate Pipeline package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2024-11-21T16:28:56+00:00" }, { - "name": "phpunit/php-timer", - "version": "5.0.3", + "name": "illuminate/session", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "url": "https://github.com/illuminate/session.git", + "reference": "a6637c73e47f6dd00f2e822b2cc4671cda824321" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/illuminate/session/zipball/a6637c73e47f6dd00f2e822b2cc4671cda824321", + "reference": "a6637c73e47f6dd00f2e822b2cc4671cda824321", "shasum": "" }, "require": { - "php": ">=7.3" + "ext-ctype": "*", + "ext-session": "*", + "illuminate/collections": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/filesystem": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2", + "symfony/finder": "^7.0.3", + "symfony/http-foundation": "^7.0.3" }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "suggest": { + "illuminate/console": "Required to use the session:table command (^11.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "11.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Illuminate\\Session\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], + "description": "The Illuminate Session package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2024-11-21T22:49:34+00:00" }, { - "name": "phpunit/phpunit", - "version": "9.6.17", + "name": "illuminate/support", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd" + "url": "https://github.com/illuminate/support.git", + "reference": "2b718a86571baed50fdc5d5748a846c2e58e07eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1a156980d78a6666721b7e8e8502fe210b587fcd", - "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd", + "url": "https://api.github.com/repos/illuminate/support/zipball/2b718a86571baed50fdc5d5748a846c2e58e07eb", + "reference": "2b718a86571baed50fdc5d5748a846c2e58e07eb", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1 || ^2", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", + "doctrine/inflector": "^2.0", + "ext-ctype": "*", + "ext-filter": "*", "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.28", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", - "sebastian/version": "^3.0.2" + "illuminate/collections": "^11.0", + "illuminate/conditionable": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/macroable": "^11.0", + "nesbot/carbon": "^2.72.2|^3.4", + "php": "^8.2", + "voku/portable-ascii": "^2.0.2" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "replace": { + "spatie/once": "*" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "illuminate/filesystem": "Required to use the composer class (^11.0).", + "laravel/serializable-closure": "Required to use the once function (^1.3).", + "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", + "ramsey/uuid": "Required to use Str::uuid() (^4.7).", + "symfony/process": "Required to use the composer class (^7.0).", + "symfony/uid": "Required to use Str::ulid() (^7.0).", + "symfony/var-dumper": "Required to use the dd function (^7.0).", + "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.6.1)." }, - "bin": [ - "phpunit" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "9.6-dev" + "dev-master": "11.x-dev" } }, "autoload": { "files": [ - "src/Framework/Assert/Functions.php" + "functions.php", + "helpers.php" ], - "classmap": [ - "src/" - ] + "psr-4": { + "Illuminate\\Support\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], + "description": "The Illuminate Support package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.17" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2024-02-23T13:14:51+00:00" + "time": "2024-11-27T14:58:17+00:00" }, { - "name": "psr/container", - "version": "2.0.2", + "name": "illuminate/view", + "version": "v11.34.2", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + "url": "https://github.com/illuminate/view.git", + "reference": "dee300a5112b6a295a3912b6fc915d03666661c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "url": "https://api.github.com/repos/illuminate/view/zipball/dee300a5112b6a295a3912b6fc915d03666661c1", + "reference": "dee300a5112b6a295a3912b6fc915d03666661c1", "shasum": "" }, "require": { - "php": ">=7.4.0" + "ext-tokenizer": "*", + "illuminate/collections": "^11.0", + "illuminate/container": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/events": "^11.0", + "illuminate/filesystem": "^11.0", + "illuminate/macroable": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "11.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Container\\": "src/" + "Illuminate\\View\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -2021,52 +2536,52 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], + "description": "The Illuminate View package.", + "homepage": "https://laravel.com", "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "time": "2021-11-05T16:47:00+00:00" + "time": "2024-11-21T16:28:56+00:00" }, { - "name": "psr/http-client", - "version": "1.0.3", + "name": "jean85/pretty-package-versions", + "version": "2.1.0", "source": { "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", - "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/3c4e5f62ba8d7de1734312e4fff32f67a8daaf10", + "reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0 || ^2.0" + "composer-runtime-api": "^2.1.0", + "php": "^7.4|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^7.5|^8.5|^9.6", + "vimeo/psalm": "^4.3 || ^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Http\\Client\\": "src/" + "Jean85\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2075,196 +2590,3495 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" } ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", + "description": "A library to get pretty versions strings of installed dependencies", "keywords": [ - "http", - "http-client", - "psr", - "psr-18" + "composer", + "package", + "release", + "versions" ], "support": { - "source": "https://github.com/php-fig/http-client" + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.0" }, - "time": "2023-09-23T14:17:50+00:00" + "time": "2024-11-18T16:19:46+00:00" }, { - "name": "psr/http-factory", - "version": "1.0.2", + "name": "laminas/laminas-escaper", + "version": "2.14.0", "source": { "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "url": "https://github.com/laminas/laminas-escaper.git", + "reference": "0f7cb975f4443cf22f33408925c231225cfba8cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/0f7cb975f4443cf22f33408925c231225cfba8cb", + "reference": "0f7cb975f4443cf22f33408925c231225cfba8cb", "shasum": "" }, "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" + "ext-ctype": "*", + "ext-mbstring": "*", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "conflict": { + "zendframework/zend-escaper": "*" + }, + "require-dev": { + "infection/infection": "^0.27.9", + "laminas/laminas-coding-standard": "~3.0.0", + "maglnet/composer-require-checker": "^3.8.0", + "phpunit/phpunit": "^9.6.16", + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.21.1" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\Http\\Message\\": "src/" + "Laminas\\Escaper\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } + "BSD-3-Clause" ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", + "homepage": "https://laminas.dev", "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" + "escaper", + "laminas" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" - }, - "time": "2023-04-10T20:10:41+00:00" - }, - { - "name": "psr/log", - "version": "2.0.0", + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-escaper/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-escaper/issues", + "rss": "https://github.com/laminas/laminas-escaper/releases.atom", + "source": "https://github.com/laminas/laminas-escaper" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2024-10-24T10:12:53+00:00" + }, + { + "name": "larastan/larastan", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/larastan/larastan.git", + "reference": "b2e24e1605cff1d1097ccb6fb8af3bbd1dfe1c6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/larastan/larastan/zipball/b2e24e1605cff1d1097ccb6fb8af3bbd1dfe1c6f", + "reference": "b2e24e1605cff1d1097ccb6fb8af3bbd1dfe1c6f", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^11.15.0", + "illuminate/container": "^11.15.0", + "illuminate/contracts": "^11.15.0", + "illuminate/database": "^11.15.0", + "illuminate/http": "^11.15.0", + "illuminate/pipeline": "^11.15.0", + "illuminate/support": "^11.15.0", + "php": "^8.2", + "phpmyadmin/sql-parser": "^5.9.0", + "phpstan/phpstan": "^2.0.2" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0", + "laravel/framework": "^11.15.0", + "mockery/mockery": "^1.6", + "nikic/php-parser": "^5.3", + "orchestra/canvas": "^v9.1.3", + "orchestra/testbench-core": "^9.5.2", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpunit/phpunit": "^10.5.16" + }, + "suggest": { + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Larastan\\Larastan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Can Vural", + "email": "can9119@gmail.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel", + "keywords": [ + "PHPStan", + "code analyse", + "code analysis", + "larastan", + "laravel", + "package", + "php", + "static analysis" + ], + "support": { + "issues": "https://github.com/larastan/larastan/issues", + "source": "https://github.com/larastan/larastan/tree/v3.0.2" + }, + "funding": [ + { + "url": "https://github.com/canvural", + "type": "github" + } + ], + "time": "2024-11-26T23:15:21+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.18.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "cef51821608239040ab841ad6e1c6ae502ae3026" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/cef51821608239040ab841ad6e1c6ae502ae3026", + "reference": "cef51821608239040ab841ad6e1c6ae502ae3026", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.65.0", + "illuminate/view": "^10.48.24", + "larastan/larastan": "^2.9.11", + "laravel-zero/framework": "^10.4.0", + "mockery/mockery": "^1.6.12", + "nunomaduro/termwind": "^1.17.0", + "pestphp/pest": "^2.36.0" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2024-11-26T15:34:00+00:00" + }, + { + "name": "laravel/prompts", + "version": "v0.3.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/0e0535747c6b8d6d10adca8b68293cf4517abb0f", + "reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "ext-mbstring": "*", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "illuminate/collections": "^10.0|^11.0", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3|^3.4", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.3.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.3.2" + }, + "time": "2024-11-12T14:59:47+00:00" + }, + { + "name": "league/color-extractor", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/color-extractor.git", + "reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/21fcac6249c5ef7d00eb83e128743ee6678fe505", + "reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "php": "^7.3 || ^8.0" + }, + "replace": { + "matthecat/colorextractor": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-curl": "To download images from remote URLs if allow_url_fopen is disabled for security reasons" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\ColorExtractor\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathieu Lechat", + "email": "math.lechat@gmail.com", + "homepage": "http://matthecat.com", + "role": "Developer" + } + ], + "description": "Extract colors from an image as a human would do.", + "homepage": "https://github.com/thephpleague/color-extractor", + "keywords": [ + "color", + "extract", + "human", + "image", + "palette" + ], + "support": { + "issues": "https://github.com/thephpleague/color-extractor/issues", + "source": "https://github.com/thephpleague/color-extractor/tree/0.4.0" + }, + "time": "2022-09-24T15:57:16+00:00" + }, + { + "name": "michelf/php-smartypants", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-smartypants.git", + "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-smartypants/zipball/47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", + "reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Michelf": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP SmartyPants", + "homepage": "https://michelf.ca/projects/php-smartypants/", + "keywords": [ + "dashes", + "quotes", + "spaces", + "typographer", + "typography" + ], + "support": { + "issues": "https://github.com/michelf/php-smartypants/issues", + "source": "https://github.com/michelf/php-smartypants/tree/1.8.1" + }, + "time": "2016-12-13T01:01:17+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2024-11-08T17:47:46+00:00" + }, + { + "name": "nesbot/carbon", + "version": "3.8.2", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e1268cdbc486d97ce23fef2c666dc3c6b6de9947", + "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "<100.0", + "ext-json": "*", + "php": "^8.1", + "psr/clock": "^1.0", + "symfony/clock": "^6.3 || ^7.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation": "^4.4.18 || ^5.2.1|| ^6.0 || ^7.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.57.2", + "kylekatarnls/multi-tester": "^2.5.3", + "ondrejmirtes/better-reflection": "^6.25.0.4", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.11.2", + "phpunit/phpunit": "^10.5.20", + "squizlabs/php_codesniffer": "^3.9.0" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev", + "dev-2.x": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2024-11-07T17:46:48+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.3.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" + }, + "time": "2024-10-08T18:51:32+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v8.5.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "f5c101b929c958e849a633283adff296ed5f38f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f5c101b929c958e849a633283adff296ed5f38f5", + "reference": "f5c101b929c958e849a633283adff296ed5f38f5", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.16.0", + "nunomaduro/termwind": "^2.1.0", + "php": "^8.2.0", + "symfony/console": "^7.1.5" + }, + "conflict": { + "laravel/framework": "<11.0.0 || >=12.0.0", + "phpunit/phpunit": "<10.5.1 || >=12.0.0" + }, + "require-dev": { + "larastan/larastan": "^2.9.8", + "laravel/framework": "^11.28.0", + "laravel/pint": "^1.18.1", + "laravel/sail": "^1.36.0", + "laravel/sanctum": "^4.0.3", + "laravel/tinker": "^2.10.0", + "orchestra/testbench-core": "^9.5.3", + "pestphp/pest": "^2.36.0 || ^3.4.0", + "sebastian/environment": "^6.1.0 || ^7.2.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + }, + "branch-alias": { + "dev-8.x": "8.x-dev" + } + }, + "autoload": { + "files": [ + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-10-15T16:06:32+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/52915afe6a1044e8b9cee1bcff836fb63acf9cda", + "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.1.8" + }, + "require-dev": { + "illuminate/console": "^11.33.2", + "laravel/pint": "^1.18.2", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0", + "phpstan/phpstan": "^1.12.11", + "phpstan/phpstan-strict-rules": "^1.6.1", + "symfony/var-dumper": "^7.1.8", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2024-11-21T10:39:51+00:00" + }, + { + "name": "pestphp/pest", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest.git", + "reference": "179d46ce97d52bcb3f791449ae94025c3f32e3e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest/zipball/179d46ce97d52bcb3f791449ae94025c3f32e3e3", + "reference": "179d46ce97d52bcb3f791449ae94025c3f32e3e3", + "shasum": "" + }, + "require": { + "brianium/paratest": "^7.6.0", + "nunomaduro/collision": "^8.5.0", + "nunomaduro/termwind": "^2.2.0", + "pestphp/pest-plugin": "^3.0.0", + "pestphp/pest-plugin-arch": "^3.0.0", + "pestphp/pest-plugin-mutate": "^3.0.5", + "php": "^8.2.0", + "phpunit/phpunit": "^11.4.3" + }, + "conflict": { + "filp/whoops": "<2.16.0", + "phpunit/phpunit": ">11.4.3", + "sebastian/exporter": "<6.0.0", + "webmozart/assert": "<1.11.0" + }, + "require-dev": { + "pestphp/pest-dev-tools": "^3.3.0", + "pestphp/pest-plugin-type-coverage": "^3.1.0", + "symfony/process": "^7.1.6" + }, + "bin": [ + "bin/pest" + ], + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Mutate\\Plugins\\Mutate", + "Pest\\Plugins\\Configuration", + "Pest\\Plugins\\Bail", + "Pest\\Plugins\\Cache", + "Pest\\Plugins\\Coverage", + "Pest\\Plugins\\Init", + "Pest\\Plugins\\Environment", + "Pest\\Plugins\\Help", + "Pest\\Plugins\\Memory", + "Pest\\Plugins\\Only", + "Pest\\Plugins\\Printer", + "Pest\\Plugins\\ProcessIsolation", + "Pest\\Plugins\\Profile", + "Pest\\Plugins\\Retry", + "Pest\\Plugins\\Snapshot", + "Pest\\Plugins\\Verbose", + "Pest\\Plugins\\Version", + "Pest\\Plugins\\Parallel" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php", + "src/Pest.php" + ], + "psr-4": { + "Pest\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "The elegant PHP Testing Framework.", + "keywords": [ + "framework", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/pestphp/pest/issues", + "source": "https://github.com/pestphp/pest/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-10-31T16:12:45+00:00" + }, + { + "name": "pestphp/pest-plugin", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin.git", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/e79b26c65bc11c41093b10150c1341cc5cdbea83", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0.0", + "composer-runtime-api": "^2.2.2", + "php": "^8.2" + }, + "conflict": { + "pestphp/pest": "<3.0.0" + }, + "require-dev": { + "composer/composer": "^2.7.9", + "pestphp/pest": "^3.0.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Pest\\Plugin\\Manager" + }, + "autoload": { + "psr-4": { + "Pest\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest plugin manager", + "keywords": [ + "framework", + "manager", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-09-08T23:21:41+00:00" + }, + { + "name": "pestphp/pest-plugin-arch", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-arch.git", + "reference": "0a27e55a270cfe73d8cb70551b91002ee2cb64b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/0a27e55a270cfe73d8cb70551b91002ee2cb64b0", + "reference": "0a27e55a270cfe73d8cb70551b91002ee2cb64b0", + "shasum": "" + }, + "require": { + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "ta-tikoma/phpunit-architecture-test": "^0.8.4" + }, + "require-dev": { + "pestphp/pest": "^3.0.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Arch\\Plugin" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Arch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Arch plugin for Pest PHP.", + "keywords": [ + "arch", + "architecture", + "framework", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-09-08T23:23:55+00:00" + }, + { + "name": "pestphp/pest-plugin-mutate", + "version": "v3.0.5", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-mutate.git", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.2.0", + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "psr/simple-cache": "^3.0.0" + }, + "require-dev": { + "pestphp/pest": "^3.0.8", + "pestphp/pest-dev-tools": "^3.0.0", + "pestphp/pest-plugin-type-coverage": "^3.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Pest\\Mutate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sandro Gehri", + "email": "sandrogehri@gmail.com" + } + ], + "description": "Mutates your code to find untested cases", + "keywords": [ + "framework", + "mutate", + "mutation", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v3.0.5" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/gehrisandro", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-09-22T07:54:40+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.6.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/f3558a4c23426d12bffeaab463f8a8d8b681193c", + "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.0" + }, + "time": "2024-11-12T11:25:25+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" + }, + "time": "2024-11-09T15:12:26+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.9.2", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "a7b17b42fa4887c92146243f3d2f4ccb962af17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a7b17b42fa4887c92146243f3d2f4ccb962af17c", + "reference": "a7b17b42fa4887c92146243f3d2f4ccb962af17c", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "doctrine/annotations": "^1.2.6 || ^1.13.3", + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.7.2", + "yoast/phpunit-polyfills": "^1.0.4" + }, + "suggest": { + "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "ext-openssl": "Needed for secure SMTP sending and DKIM signing", + "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", + "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.2" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2024-10-09T10:07:50+00:00" + }, + { + "name": "phpmyadmin/sql-parser", + "version": "5.10.1", + "source": { + "type": "git", + "url": "https://github.com/phpmyadmin/sql-parser.git", + "reference": "b14fd66496a22d8dd7f7e2791edd9e8674422f17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/b14fd66496a22d8dd7f7e2791edd9e8674422f17", + "reference": "b14fd66496a22d8dd7f7e2791edd9e8674422f17", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "phpmyadmin/motranslator": "<3.0" + }, + "require-dev": { + "phpbench/phpbench": "^1.1", + "phpmyadmin/coding-standard": "^3.0", + "phpmyadmin/motranslator": "^4.0 || ^5.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.9.12", + "phpstan/phpstan-phpunit": "^1.3.3", + "phpunit/phpunit": "^8.5 || ^9.6", + "psalm/plugin-phpunit": "^0.16.1", + "vimeo/psalm": "^4.11", + "zumba/json-serializer": "~3.0.2" + }, + "suggest": { + "ext-mbstring": "For best performance", + "phpmyadmin/motranslator": "Translate messages to your favorite locale" + }, + "bin": [ + "bin/highlight-query", + "bin/lint-query", + "bin/sql-parser", + "bin/tokenize-query" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpMyAdmin\\SqlParser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "The phpMyAdmin Team", + "email": "developers@phpmyadmin.net", + "homepage": "https://www.phpmyadmin.net/team/" + } + ], + "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", + "homepage": "https://github.com/phpmyadmin/sql-parser", + "keywords": [ + "analysis", + "lexer", + "parser", + "query linter", + "sql", + "sql lexer", + "sql linter", + "sql parser", + "sql syntax highlighter", + "sql tokenizer" + ], + "support": { + "issues": "https://github.com/phpmyadmin/sql-parser/issues", + "source": "https://github.com/phpmyadmin/sql-parser" + }, + "funding": [ + { + "url": "https://www.phpmyadmin.net/donate/", + "type": "other" + } + ], + "time": "2024-11-10T04:10:31+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.0" + }, + "time": "2024-10-13T11:29:49+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "46b4d3529b12178112d9008337beda0cc2a1a6b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/46b4d3529b12178112d9008337beda0cc2a1a6b4", + "reference": "46b4d3529b12178112d9008337beda0cc2a1a6b4", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2024-11-28T22:19:37+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7f08030e8811582cc459871d28d6f5a1a4d35ca", + "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.3.1", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^11.4.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T06:21:38+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e8e8ed1854de5d36c088ec1833beae40d2dedd76", + "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.7", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.1", + "sebastian/comparator": "^6.1.1", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.1.3", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.4-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.3" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-10-28T13:07:50+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2022-12-31T21:50:55+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.7.6", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.7.6" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2024-04-27T21:32:50+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:44:28+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-31T05:30:08+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:54:44+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:56:19+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376", - "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": ">=8.0.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { - "source": "https://github.com/php-fig/log/tree/2.0.0" + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, - "time": "2021-07-14T16:41:46+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" }, { - "name": "ralouphie/getallheaders", - "version": "3.0.3", + "name": "sebastian/object-reflector", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=8.2" }, "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" + "phpunit/phpunit": "^11.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, "autoload": { - "files": [ - "src/getallheaders.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "A polyfill for getallheaders.", + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, - "time": "2019-03-08T08:55:37+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" }, { - "name": "sebastian/cli-parser", - "version": "1.0.1", + "name": "sebastian/recursion-context", + "version": "6.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2279,15 +6093,23 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" }, "funding": [ { @@ -2295,32 +6117,32 @@ "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2024-07-03T05:10:34+00:00" }, { - "name": "sebastian/code-unit", - "version": "1.0.8", + "name": "sebastian/type", + "version": "5.1.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -2339,11 +6161,12 @@ "role": "lead" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" }, "funding": [ { @@ -2351,32 +6174,29 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2024-09-17T13:12:04+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "name": "sebastian/version", + "version": "5.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2391,858 +6211,1304 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.6.3", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "7c18db2bc667ac84e5d7c18e33f16c38ff2d8838" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/7c18db2bc667ac84e5d7c18e33f16c38ff2d8838", + "reference": "7c18db2bc667ac84e5d7c18e33f16c38ff2d8838", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "laravel/serializable-closure": "^1.3", + "phpunit/phpunit": "^9.3", + "spatie/phpunit-snapshot-assertions": "^4.2", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/backtrace/tree/1.6.3" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2024-11-18T14:58:58+00:00" + }, + { + "name": "spatie/macroable", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/macroable.git", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/macroable/zipball/ec2c320f932e730607aff8052c44183cf3ecb072", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Macroable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A trait to dynamically add methods to a class", + "homepage": "https://github.com/spatie/macroable", + "keywords": [ + "macroable", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/macroable/issues", + "source": "https://github.com/spatie/macroable/tree/2.0.0" + }, + "time": "2021-03-26T22:39:02+00:00" + }, + { + "name": "spatie/ray", + "version": "1.41.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/ray.git", + "reference": "c44f8cfbf82c69909b505de61d8d3f2d324e93fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ray/zipball/c44f8cfbf82c69909b505de61d8d3f2d324e93fc", + "reference": "c44f8cfbf82c69909b505de61d8d3f2d324e93fc", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": "^7.3|^8.0", + "ramsey/uuid": "^3.0|^4.1", + "spatie/backtrace": "^1.1", + "spatie/macroable": "^1.0|^2.0", + "symfony/stopwatch": "^4.0|^5.1|^6.0|^7.0", + "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0.3" + }, + "require-dev": { + "illuminate/support": "6.x|^8.18|^9.0", + "nesbot/carbon": "^2.63", + "pestphp/pest": "^1.22", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.19.2", + "spatie/phpunit-snapshot-assertions": "^4.2", + "spatie/test-time": "^1.2" + }, + "bin": [ + "bin/remove-ray.sh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Ray\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Debug with Ray to fix problems faster", + "homepage": "https://github.com/spatie/ray", + "keywords": [ + "ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/ray/issues", + "source": "https://github.com/spatie/ray/tree/1.41.2" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/sponsors/spatie", "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2024-04-24T14:21:46+00:00" }, { - "name": "sebastian/comparator", - "version": "4.0.8", + "name": "symfony/clock", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "url": "https://github.com/symfony/clock.git", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "provide": { + "psr/clock-implementation": "1.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", "keywords": [ - "comparator", - "compare", - "equality" + "clock", + "psr20", + "time" ], "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "source": "https://github.com/symfony/clock/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { - "name": "sebastian/complexity", - "version": "2.0.3", + "name": "symfony/console", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + "url": "https://github.com/symfony/console.git", + "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", + "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + "source": "https://github.com/symfony/console/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-12-22T06:19:30+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { - "name": "sebastian/diff", - "version": "4.0.5", + "name": "symfony/deprecation-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "classmap": [ - "src/" + "files": [ + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-05-07T05:35:17+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { - "name": "sebastian/environment", - "version": "5.1.5", + "name": "symfony/error-handler", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + "url": "https://github.com/symfony/error-handler.git", + "reference": "672b3dd1ef8b87119b446d67c58c106c43f965fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/672b3dd1ef8b87119b446d67c58c106c43f965fe", + "reference": "672b3dd1ef8b87119b446d67c58c106c43f965fe", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^6.4|^7.0" }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" }, - "suggest": { - "ext-posix": "*" + "require-dev": { + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + "source": "https://github.com/symfony/error-handler/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T06:03:51+00:00" + "time": "2024-11-05T15:35:02+00:00" }, { - "name": "sebastian/exporter", - "version": "4.0.5", + "name": "symfony/event-dispatcher", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { - "name": "sebastian/global-state", - "version": "5.0.6", + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bde739e7565280bda77be70044ac1047bc007e34" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", - "reference": "bde739e7565280bda77be70044ac1047bc007e34", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", "keywords": [ - "global state" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-08-02T09:26:13+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { - "name": "sebastian/lines-of-code", - "version": "1.0.4", + "name": "symfony/finder", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + "url": "https://github.com/symfony/finder.git", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "symfony/filesystem": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + "source": "https://github.com/symfony/finder/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-12-22T06:20:34+00:00" + "time": "2024-10-23T06:56:12+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "4.0.4", + "name": "symfony/http-foundation", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "url": "https://github.com/symfony/http-foundation.git", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e88a66c3997859532bc2ddd6dd8f35aba2711744", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "source": "https://github.com/symfony/http-foundation/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2024-11-13T18:58:46+00:00" }, { - "name": "sebastian/object-reflector", - "version": "2.0.4", + "name": "symfony/http-kernel", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "url": "https://github.com/symfony/http-kernel.git", + "reference": "6b4722a25e0aed1ccb4914b9bcbd493cc4676b4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6b4722a25e0aed1ccb4914b9bcbd493cc4676b4d", + "reference": "6b4722a25e0aed1ccb4914b9bcbd493cc4676b4d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^7.1", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.12" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "source": "https://github.com/symfony/http-kernel/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2024-11-29T08:42:40+00:00" }, { - "name": "sebastian/recursion-context", - "version": "4.0.5", + "name": "symfony/mime", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "url": "https://github.com/symfony/mime.git", + "reference": "cc84a4b81f62158c3846ac7ff10f696aae2b524d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/symfony/mime/zipball/cc84a4b81f62158c3846ac7ff10f696aae2b524d", + "reference": "cc84a4b81f62158c3846ac7ff10f696aae2b524d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + "source": "https://github.com/symfony/mime/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T06:07:39+00:00" + "time": "2024-11-23T09:19:39+00:00" }, { - "name": "sebastian/resource-operations", - "version": "3.0.3", + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^9.0" + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "3.0-dev" + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/type", - "version": "3.2.1", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^9.5" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "3.2-dev" + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T06:13:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/version", - "version": "3.0.2", + "name": "symfony/polyfill-intl-idn", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "3.0-dev" + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/config", - "version": "v7.0.4", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "44deeba7233f08f383185ffa37dace3b3bc87364" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/44deeba7233f08f383185ffa37dace3b3bc87364", - "reference": "44deeba7233f08f383185ffa37dace3b3bc87364", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/filesystem": "^6.4|^7.0", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/finder": "<6.4", - "symfony/service-contracts": "<2.5" + "php": ">=7.2" }, - "require-dev": { - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^6.4|^7.0" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Config\\": "" + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -3251,18 +7517,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/config/tree/v7.0.4" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -3278,59 +7552,45 @@ "type": "tidelift" } ], - "time": "2024-02-26T07:52:39+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/console", - "version": "v7.0.4", + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "6b099f3306f7c9c2d2786ed736d0026b2903205f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/6b099f3306f7c9c2d2786ed736d0026b2903205f", - "reference": "6b099f3306f7c9c2d2786ed736d0026b2903205f", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3338,24 +7598,25 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Eases the creation of beautiful and testable command line interfaces", + "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", "keywords": [ - "cli", - "command-line", - "console", - "terminal" + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.0.4" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -3371,38 +7632,41 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:20+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "name": "symfony/polyfill-php80", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { "files": [ - "function.php" + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -3410,6 +7674,10 @@ "MIT" ], "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -3419,10 +7687,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "A generic function and convention to trigger deprecation notices", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -3438,34 +7712,41 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/filesystem", - "version": "v7.0.3", + "name": "symfony/polyfill-php83", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/2890e3a825bc0c0558526c04499c13f83e1b6b12", - "reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" + "php": ">=7.2" }, "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Filesystem\\": "" + "Symfony\\Polyfill\\Php83\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -3474,18 +7755,24 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides basic utilities for the filesystem", + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.0.3" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" }, "funding": [ { @@ -3501,45 +7788,33 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "name": "symfony/process", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "url": "https://github.com/symfony/process.git", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" + "php": ">=8.2" }, "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3547,24 +7822,18 @@ ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/process/tree/v7.2.0" }, "funding": [ { @@ -3580,42 +7849,47 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", + "name": "symfony/service-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, - "suggest": { - "ext-intl": "For best performance" + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3631,18 +7905,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's grapheme_* functions", + "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -3658,47 +7932,34 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { - "name": "symfony/polyfill-intl-idn", - "version": "v1.28.0", + "name": "symfony/stopwatch", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "696f418b0d722a4225e1c3d95489d262971ca924" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/696f418b0d722a4225e1c3d95489d262971ca924", + "reference": "696f418b0d722a4225e1c3d95489d262971ca924", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3706,30 +7967,18 @@ ], "authors": [ { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "description": "Provides a way to profile code", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0" + "source": "https://github.com/symfony/stopwatch/tree/v7.2.0" }, "funding": [ { @@ -3745,44 +7994,50 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:30:37+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", + "name": "symfony/string", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "url": "https://github.com/symfony/string.git", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" }, - "suggest": { - "ext-intl": "For best performance" + "conflict": { + "symfony/translation-contracts": "<2.5" }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" }, + "type": "library", "autoload": { "files": [ - "bootstrap.php" + "Resources/functions.php" ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + "Symfony\\Component\\String\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -3799,18 +8054,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -3826,48 +8081,67 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", + "name": "symfony/translation", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" + "url": "https://github.com/symfony/translation.git", + "reference": "dc89e16b44048ceecc879054e5b7f38326ab6cc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", + "url": "https://api.github.com/repos/symfony/translation/zipball/dc89e16b44048ceecc879054e5b7f38326ab6cc5", + "reference": "dc89e16b44048ceecc879054e5b7f38326ab6cc5", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" }, "provide": { - "ext-mbstring": "*" + "symfony/translation-implementation": "2.3|3.0" }, - "suggest": { - "ext-mbstring": "For best performance" + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { "files": [ - "bootstrap.php" + "Resources/functions.php" ], "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3875,25 +8149,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for the Mbstring extension", + "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + "source": "https://github.com/symfony/translation/tree/v7.2.0" }, "funding": [ { @@ -3909,33 +8176,29 @@ "type": "tidelift" } ], - "time": "2023-07-28T09:04:16+00:00" + "time": "2024-11-12T20:47:56+00:00" }, { - "name": "symfony/service-contracts", - "version": "v3.4.1", + "name": "symfony/translation-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0" - }, - "conflict": { - "ext-psr": "<1.1|>=2" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -3944,7 +8207,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Contracts\\Service\\": "" + "Symfony\\Contracts\\Translation\\": "" }, "exclude-from-classmap": [ "/Test/" @@ -3964,7 +8227,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to writing services", + "description": "Generic abstractions related to translation", "homepage": "https://symfony.com", "keywords": [ "abstractions", @@ -3975,7 +8238,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -3991,30 +8254,47 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { - "name": "symfony/stopwatch", - "version": "v7.0.3", + "name": "symfony/var-dumper", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112" + "url": "https://github.com/symfony/var-dumper.git", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/983900d6fddf2b0cbaacacbbad07610854bd8112", - "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/service-contracts": "^2.5|^3" + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<6.4" }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], "type": "library", "autoload": { + "files": [ + "Resources/functions/dump.php" + ], "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" + "Symfony\\Component\\VarDumper\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -4026,18 +8306,22 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a way to profile code", + "description": "Provides mechanisms for walking through any arbitrary PHP variable", "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.0.3" + "source": "https://github.com/symfony/var-dumper/tree/v7.2.0" }, "funding": [ { @@ -4053,46 +8337,39 @@ "type": "tidelift" } ], - "time": "2024-01-23T15:02:46+00:00" + "time": "2024-11-08T15:48:14+00:00" }, { - "name": "symfony/string", - "version": "v7.0.4", + "name": "symfony/yaml", + "version": "v7.1.6", "source": { "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b" + "url": "https://github.com/symfony/yaml.git", + "reference": "3ced3f29e4f0d6bce2170ff26719f1fe9aacc671" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b", - "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3ced3f29e4f0d6bce2170ff26719f1fe9aacc671", + "reference": "3ced3f29e4f0d6bce2170ff26719f1fe9aacc671", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/translation-contracts": "<2.5" + "symfony/console": "<6.4" }, "require-dev": { - "symfony/error-handler": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/console": "^6.4|^7.0" }, + "bin": [ + "Resources/bin/yaml-lint" + ], "type": "library", "autoload": { - "files": [ - "Resources/functions.php" - ], "psr-4": { - "Symfony\\Component\\String\\": "" + "Symfony\\Component\\Yaml\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -4104,26 +8381,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], "support": { - "source": "https://github.com/symfony/string/tree/v7.0.4" + "source": "https://github.com/symfony/yaml/tree/v7.1.6" }, "funding": [ { @@ -4139,44 +8408,38 @@ "type": "tidelift" } ], - "time": "2024-02-01T13:17:36+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { - "name": "symfony/yaml", - "version": "v6.4.0", + "name": "ta-tikoma/phpunit-architecture-test", + "version": "0.8.4", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587" + "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587", - "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/89f0dea1cb0f0d5744d3ec1764a286af5e006636", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<5.4" + "nikic/php-parser": "^4.18.0 || ^5.0.0", + "php": "^8.1.0", + "phpdocumentor/reflection-docblock": "^5.3.0", + "phpunit/phpunit": "^10.5.5 || ^11.0.0", + "symfony/finder": "^6.4.0 || ^7.0.0" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "laravel/pint": "^1.13.7", + "phpstan/phpstan": "^1.10.52" }, - "bin": [ - "Resources/bin/yaml-lint" - ], "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "PHPUnit\\Architecture\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4184,47 +8447,40 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Ni Shi", + "email": "futik0ma011@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" } ], - "description": "Loads and dumps YAML files", - "homepage": "https://symfony.com", + "description": "Methods for testing application architecture", + "keywords": [ + "architecture", + "phpunit", + "stucture", + "test", + "testing" + ], "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.0" + "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.4" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-11-06T11:00:25+00:00" + "time": "2024-01-05T14:10:56+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -4253,7 +8509,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.2" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -4261,17 +8517,151 @@ "type": "github" } ], - "time": "2023-11-20T00:12:19+00:00" + "time": "2024-03-03T12:36:25+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "https://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.3" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2024-11-21T01:49:47+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "getkirby/cms": 15 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=8.1.0" + "php": ">=8.2.0" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/index.php b/index.php index 4f5674b..9042e49 100644 --- a/index.php +++ b/index.php @@ -1,54 +1,18 @@ [ - 'enabled' => null, // null => disable in panel and api + 'enabled' => null, // null => auto-detection: disable in debug-mode, panel and api 'seed' => function () { return Url::stripPath(site()->url()); }, - 'headers' => [ - "X-Powered-By" => "", // unset - "X-Frame-Options" => "DENY", - "X-XSS-Protection" => "1; mode=block", - "X-Content-Type-Options" => "nosniff", - "strict-transport-security" => "max-age=31536000; includeSubdomains; preload", - "Referrer-Policy" => "no-referrer-when-downgrade", - "Permissions-Policy" => 'interest-cohort=()', // flock-off - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy - "Feature-Policy" => [ - "accelerometer 'none'", - "ambient-light-sensor 'none'", - "autoplay 'none'", - "battery 'none'", - "camera 'none'", - "display-capture 'none'", - "document-domain 'none'", - "encrypted-media 'none'", - "execution-while-not-rendered 'none'", - "execution-while-out-of-viewport 'none'", - "fullscreen 'none'", - "geolocation 'none'", - "gyroscope 'none'", - "layout-animations 'none'", - "legacy-image-formats 'none'", - "magnetometer 'none'", - "microphone 'none'", - "midi 'none'", - "navigation-override 'none'", - "oversized-images 'none'", - "payment 'none'", - "picture-in-picture 'none'", - "publickey-credentials 'none'", - "sync-xhr 'none'", - "usb 'none'", - "wake-lock 'none'", - "xr-spatial-tracking 'none'", - ], - ], + 'headers' => function () { + return \Bnomei\SecurityHeaders::HEADERS_DEFAULT; + }, 'loader' => function () { // https://github.com/paragonie/csp-builder#example // null if you do NOT want to use default and/or just the setter @@ -62,10 +26,10 @@ return kirby()->roots()->site() . '/your-csp.json'; return kirby()->roots()->site() . '/your-csp.yml'; */ - // otherwise forward the default file from this plugin - return __DIR__ . '/loader.json'; + + return \Bnomei\SecurityHeaders::LOADER_DEFAULT; }, - 'setter' => function (SecurityHeaders $instance): void { + 'setter' => function (\Bnomei\SecurityHeaders $instance): void { // https://github.com/paragonie/csp-builder#build-a-content-security-policy-programmatically /* $csp = $instance->csp(); @@ -83,18 +47,18 @@ ], 'hooks' => [ 'route:before' => function (): void { - SecurityHeaders::singleton()->sendHeaders(); + \Bnomei\SecurityHeaders::singleton()->sendHeaders(); }, ], 'pageMethods' => [ 'nonce' => function (string $key): ?string { - return SecurityHeaders::singleton()->getNonce($key); + return \Bnomei\SecurityHeaders::singleton()->getNonce($key); }, 'nonceAttr' => function (string $key): string { return implode( [ 'nonce="', - SecurityHeaders::singleton()->getNonce($key), + \Bnomei\SecurityHeaders::singleton()->getNonce($key), '"', ] ); @@ -102,13 +66,13 @@ ], 'siteMethods' => [ 'nonce' => function (): ?string { - return SecurityHeaders::singleton()->getNonce(Url::stripPath(site()->url())); + return \Bnomei\SecurityHeaders::singleton()->getNonce(Url::stripPath(site()->url())); }, 'nonceAttr' => function (): string { return implode( [ 'nonce="', - SecurityHeaders::singleton()->getNonce(Url::stripPath(site()->url())), + \Bnomei\SecurityHeaders::singleton()->getNonce(Url::stripPath(site()->url())), '"', ] ); diff --git a/loader.json b/loader.json deleted file mode 100644 index 9c3ce98..0000000 --- a/loader.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "report-only": false, - "base-uri": { - "self": true - }, - "default-src": { - "self": true - }, - "connect-src": { - "self": true - }, - "font-src": { - "self": true - }, - "form-action": { - "allow": [], - "self": true - }, - "frame-ancestors": [], - "frame-src": { - "allow": [], - "self": false - }, - "img-src": { - "self": true, - "data": true - }, - "media-src": [], - "object-src": [], - "plugin-types": [], - "script-src": { - "allow": [], - "hashes": [], - "self": true, - "unsafe-inline": false, - "unsafe-eval": false - }, - "style-src": { - "self": true - }, - "upgrade-insecure-requests": true, - "worker-src": { - "allow": [], - "self": false - } -} diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..5ff68be --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,14 @@ +parameters: + level: 9 + paths: + - classes + - index.php + excludePaths: + - tests + + ignoreErrors: + # - '#Undefined variable: \$this#' + - '#Parameter \#1 \$value of function strval expects#' + - '#Call to an undefined method Kirby\\Cms\\Ingredients::#' + - + identifier: missingType.iterableValue diff --git a/phpunit.xml b/phpunit.xml index f72a166..5a1159f 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,11 +1,7 @@ @@ -20,11 +16,13 @@ - - classes - - + + + + classes + + diff --git a/pint.json b/pint.json new file mode 100644 index 0000000..50d38a0 --- /dev/null +++ b/pint.json @@ -0,0 +1,6 @@ +{ + "exclude": [ + "tests/kirby", + "vendor" + ] +} diff --git a/ray.php b/ray.php new file mode 100644 index 0000000..551369d --- /dev/null +++ b/ray.php @@ -0,0 +1,35 @@ + true, + + /* + * The host used to communicate with the Ray app. + */ + 'host' => 'localhost', + + /* + * The port number used to communicate with the Ray app. + */ + 'port' => 23517, + + /* + * Absolute base path for your sites or projects in Homestead, Vagrant, Docker, or another remote development server. + */ + 'remote_path' => __DIR__, + + /* + * Absolute base path for your sites or projects on your local computer where your IDE or code editor is running on. + */ + 'local_path' => __DIR__, + + /* + * When this setting is enabled, the package will not try to format values sent to Ray. + */ + 'always_send_raw_values' => false, +]; diff --git a/readme.md b/readme.md index 303609f..3e4ca92 100644 --- a/readme.md +++ b/readme.md @@ -1,156 +1,170 @@ # Kirby Content Security Policy Header -![Release](https://flat.badgen.net/packagist/v/bnomei/kirby3-security-headers?color=ae81ff) -![Downloads](https://flat.badgen.net/packagist/dt/bnomei/kirby3-security-headers?color=272822) -[![Build Status](https://flat.badgen.net/travis/bnomei/kirby3-security-headers)](https://travis-ci.com/bnomei/kirby3-security-headers) -[![Coverage Status](https://flat.badgen.net/coveralls/c/github/bnomei/kirby3-security-headers)](https://coveralls.io/github/bnomei/kirby3-security-headers) -[![Maintainability](https://flat.badgen.net/codeclimate/maintainability/bnomei/kirby3-security-headers)](https://codeclimate.com/github/bnomei/kirby3-security-headers) -[![Twitter](https://flat.badgen.net/badge/twitter/bnomei?color=66d9ef)](https://twitter.com/bnomei) +[![Kirby 5](https://flat.badgen.net/badge/Kirby/5?color=ECC748)](https://getkirby.com) +![PHP 8.2](https://flat.badgen.net/badge/PHP/8.2?color=4E5B93&icon=php&label) +![Release](https://flat.badgen.net/packagist/v/bnomei/kirby3-security-headers?color=ae81ff&icon=github&label) +![Downloads](https://flat.badgen.net/packagist/dt/bnomei/kirby3-security-headers?color=272822&icon=github&label) +[![Coverage](https://flat.badgen.net/codeclimate/coverage/bnomei/kirby3-security-headers?icon=codeclimate&label)](https://codeclimate.com/github/bnomei/kirby3-security-headers) +[![Maintainability](https://flat.badgen.net/codeclimate/maintainability/bnomei/kirby3-security-headers?icon=codeclimate&label)](https://codeclimate.com/github/bnomei/kirby3-security-headers/issues) +[![Discord](https://flat.badgen.net/badge/discord/bnomei?color=7289da&icon=discord&label)](https://discordapp.com/users/bnomei) +[![Buymecoffee](https://flat.badgen.net/badge/icon/donate?icon=buymeacoffee&color=FF813F&label)](https://www.buymeacoffee.com/bnomei) -Kirby Plugin for easier Security Headers setup. - -> 🔐 Why should you use this plugin? Because security matters. Protecting your own or your clients websites and their customers data is important. - -1. [Automatic Setup](https://github.com/bnomei/kirby3-security-headers#automatic) -1. [Setup: Headers](https://github.com/bnomei/kirby3-security-headers#headers) -1. [Setup: Loader](https://github.com/bnomei/kirby3-security-headers#loader) -1. [Setup: Setter](https://github.com/bnomei/kirby3-security-headers#setter) -1. [Frontend Nonce](https://github.com/bnomei/kirby3-security-headers#frontend-nonce) -1. [Settings](https://github.com/bnomei/kirby3-security-headers#settings) +Kirby Plugin for easier Content Security Policy (CSP) Headers setup. ## Installation -- unzip [master.zip](https://github.com/bnomei/kirby3-security-headers/archive/master.zip) as folder `site/plugins/kirby3-security-headers` or +- unzip [master.zip](https://github.com/bnomei/kirby3-security-headers/archive/master.zip) as folder + `site/plugins/kirby3-security-headers` or - `git submodule add https://github.com/bnomei/kirby3-security-headers.git site/plugins/kirby3-security-headers` or - `composer require bnomei/kirby3-security-headers` -## Setup +## Default CSP Headers -### Automatic +The following headers will be applied by default, you do not need to set them explicitly. They provide a good starting +point for most websites and ensure a sane level of security. -A `route:before`-hook takes care of setting the headers automatically unless one of the following conditions applies: +```yaml +X-Powered-By: "" # unset +X-Frame-Options: "SAMEORIGIN" +X-XSS-Protection: "1; mode=block" +X-Content-Type-Options: "nosniff" +Strict-Transport-Security: "max-age=31536000; includeSubdomains" +Referrer-Policy: "no-referrer-when-downgrade" +Permissions-Policy: "interest-cohort=()" # flock-off +# + various Feature-Policies... +``` -- Kirbys **global** debug mode is `true` -- Kirby determins it is a [local setup](https://github.com/getkirby/kirby/blob/03d6e96aa27f631e5311cb6c2109e1510505cab7/src/Cms/System.php#L190) -- the plugins setting `enabled` is set to `false` +> [!TIP] +> See `\Bnomei\SecurityHeaders::HEADERS_DEFAULT` for more details. -### Header +## Zero Configuration? Almost. -The following headers will be applied by default, you do not need to set them explicitly. You can override them in the config file. +Installing the plugin is enough to protect your website. A `route:before`-hook takes care of sending the CSP headers +automatically. But you will most likely need to customize the CSP headers when using third-party services like -**/site/config/config.php** -```php - [ - "X-Powered-By" => "", // unset - "X-Frame-Options" => "SAMEORIGIN", - "X-XSS-Protection" => "1; mode=block", - "X-Content-Type-Options" => "nosniff", - "strict-transport-security" => "max-age=31536000; includeSubdomains", - "Referrer-Policy" => "no-referrer-when-downgrade", - "Permissions-Policy" => 'interest-cohort=()', // flock-off, - // ... FEATURE POLICIES - // other options... -]; -``` +- Content Delivery Networks (CDN), +- analytic scripts like Google-Tag-Manager/Fathom/Matomo/Piwik/Plausible/Umami, +- embedding external media like from Youtube/Vimeo/Instagram/X, +- external newsletter sign-up forms from Brevo/Mailchimp/Mailjet/Mailcoach, +- any other third-party service not hosted on your domain or subdomain or +- when using inline ` +``` - -``` +## Disabling the plugin -> TIP: The [srcset plugin](https://github.com/bnomei/kirby3-srcset/) uses that *frontend nonce* as well. +The CSP headers will be sent before Kirby renders HTML using a `route:before` hook but the plugin will be automatically +disabled if one the following conditions apply: + +- Kirby determines it is + a [local setup](https://github.com/getkirby/kirby/blob/03d6e96aa27f631e5311cb6c2109e1510505cab7/src/Cms/System.php#L190) + or +- The plugins setting `bnomei.securityheaders.enabled` is set to `false`. + +> [!WARNING] +> By default, CSP headers are never sent for any Kirby Panel, API and Media routes. ## Settings -| bnomei.securityheaders. | Default | Description | -|---------------------------|----------------|---------------------------| -| enabled | `true or false or 'force'` | will set headers | -| seed | `callback` | returns a seed for frontend nonce | -| headers | `array` | of sensible default values. modify as needed. | -| loader | `callback` | returning filepath or array | -| setter | `callback` | instance which allows customizing the CSPBuilder | +| bnomei.securityheaders. | Default | Description | +|-------------------------|-------------------|-----------------------------------------------------------| +| enabled | `null/true/false` | will set headers | +| seed | `callback` | returns a unique seed for frontend nonces on every request | +| headers | `callback` | array of sensible default values | +| loader | `callback` | returning filepath or array | +| setter | `callback` | instance which allows customizing the CSPBuilder | ## Dependencies - - - [paragonie/csp-builder](https://github.com/paragonie/csp-builder) + +- [paragonie/csp-builder](https://github.com/paragonie/csp-builder) ## Disclaimer -This plugin is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please [create a new issue](https://github.com/bnomei/kirby3-security-headers/issues/new). +This plugin is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it +in a production environment. If you find any issues, +please [create a new issue](https://github.com/bnomei/kirby3-security-headers/issues/new). ## License [MIT](https://opensource.org/licenses/MIT) -It is discouraged to use this plugin in any project that promotes racism, sexism, homophobia, animal abuse, violence or any other form of hate speech. +It is discouraged to use this plugin in any project that promotes racism, sexism, homophobia, animal abuse, violence or +any other form of hate speech. diff --git a/tests/.htaccess b/tests/.htaccess deleted file mode 100644 index 6c57e0b..0000000 --- a/tests/.htaccess +++ /dev/null @@ -1,57 +0,0 @@ -# Kirby .htaccess - -# rewrite rules - - -# enable awesome urls. i.e.: -# http://yourdomain.com/about-us/team -RewriteEngine on - -# make sure to set the RewriteBase correctly -# if you are running the site in a subfolder. -# Otherwise links or the entire site will break. -# -# If your homepage is http://yourdomain.com/mysite -# Set the RewriteBase to: -# -# RewriteBase /mysite - -# In some environments it's necessary to -# set the RewriteBase to: -# -RewriteBase / - -# block files and folders beginning with a dot, such as .git -# except for the .well-known folder, which is used for Let's Encrypt and security.txt -RewriteRule (^|/)\.(?!well-known\/) index.php [L] - -# block text files in the content folder from being accessed directly -RewriteRule ^content/(.*)\.(txt|md|mdown)$ index.php [L] - -# block all files in the site folder from being accessed directly -# except for requests to plugin assets files -RewriteRule ^site/(.*) index.php [L] - -# Enable authentication header -SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 - -# block direct access to kirby and the panel sources -RewriteRule ^kirby/(.*) index.php [L] - -# make site links work -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule ^(.*) index.php [L] - - - -# compress text file responses - -AddOutputFilterByType DEFLATE text/plain -AddOutputFilterByType DEFLATE text/html -AddOutputFilterByType DEFLATE text/css -AddOutputFilterByType DEFLATE text/javascript -AddOutputFilterByType DEFLATE application/json -AddOutputFilterByType DEFLATE application/javascript -AddOutputFilterByType DEFLATE application/x-javascript - diff --git a/tests/SecurityheadersTest.php b/tests/SecurityheadersTest.php index 25da311..76270ea 100644 --- a/tests/SecurityheadersTest.php +++ b/tests/SecurityheadersTest.php @@ -1,171 +1,144 @@ jsonPath = __DIR__ . '/test-builder-config.json'; - $this->yamlPath = __DIR__ . '/test-builder-config.yml'; - $this->apachePath = __DIR__ . '/apache.cache'; - $this->nginxPath = __DIR__ . '/nginx.cache'; - - if (F::exists($this->jsonPath) && !F::exists($this->yamlPath)) { - $json = Json::decode(F::read($this->jsonPath)); - F::write($this->yamlPath, Yaml::encode($json)); - } - - F::remove($this->apachePath); - F::remove($this->nginxPath); - } - - public function tearDown(): void + public const PATHS = [ + 'json' => __DIR__.'/fixtures/securityheaders.json', + 'yaml' => __DIR__.'/fixtures/securityheaders.yml', + 'apache' => __DIR__.'/fixtures/.htaccess', + 'nginx' => __DIR__.'/fixtures/nginx.conf', + ]; + + public function __construct( + public string $json, + public string $yaml, + public string $apache, + public string $nginx, + ) {} + + public function before(): void { - F::remove($this->apachePath); - F::remove($this->nginxPath); - } - - public function testConstruct() - { - $sec = new Bnomei\SecurityHeaders(); - $this->assertInstanceOf(SecurityHeaders::class, $sec); - } - - public function testOptions() - { - $sec = new Bnomei\SecurityHeaders(); - $this->assertIsArray($sec->option()); - $this->assertCount(8, $sec->option()); - - $this->assertTrue($sec->option('debug')); // config "force" - - $sec = new Bnomei\SecurityHeaders([ - 'debug' => true, - 'enabled' => function () { - return false; - } - ]); - $this->assertTrue($sec->option('debug')); - $this->assertFalse($sec->option('enabled')); - } - - public function testCsp() - { - $sec = new Bnomei\SecurityHeaders(); - $this->assertNull($sec->csp()); - - $builder = $sec->load(); - $this->assertInstanceOf(CSPBuilder::class, $builder); - $this->assertEquals($builder, $sec->csp()); - } - - public function testLoad() - { - $sec = new Bnomei\SecurityHeaders(); - $builder = $sec->load([]); - $this->assertInstanceOf(CSPBuilder::class, $builder); - - $builder = $sec->load($this->jsonPath); - $this->assertInstanceOf(CSPBuilder::class, $builder); - - $builder = $sec->load($this->yamlPath); - $this->assertInstanceOf(CSPBuilder::class, $builder); + F::remove($this->apache); + F::remove($this->nginx); - $builder = $sec->load(Json::decode(F::read($this->jsonPath))); - $this->assertInstanceOf(CSPBuilder::class, $builder); - } - - public function testApplySetter() - { - $sec = new Bnomei\SecurityHeaders([ - 'setter' => function (SecurityHeaders $instance) { - $instance->saveApache($this->apachePath); - }, - ]); - $sec->load(); - $sec->applySetter(); - $this->assertTrue(F::exists($this->apachePath)); - } - - public function testSave() - { - $sec = SecurityHeaders::singleton(); - $this->assertTrue($sec->saveApache($this->apachePath)); - $this->assertTrue($sec->saveNginx($this->nginxPath)); - } - - public function testSingleton() - { - $sec = SecurityHeaders::singleton(); - $this->assertInstanceOf(SecurityHeaders::class, $sec); - } - - public function testSendHeadersDisabled() - { - $sec = new Bnomei\SecurityHeaders([ - 'enabled' => false, // force against localhost check - ]); - $sec->load(); - $this->assertFalse($sec->sendHeaders()); - } - - public function testForceEnabled() - { - $sec = new Bnomei\SecurityHeaders([ - 'debug' => true, - 'enabled' => 'force', - 'headers' => [], // no default headers to test covage from sendCSPHeader - ]); - $sec->load(); - $this->expectExceptionMessageMatches( - '/^Headers already sent!*$/' - ); - $this->assertFalse($sec->sendHeaders()); - } - - public function testSendHeadersCSPOnly() - { - $sec = new Bnomei\SecurityHeaders([ - 'enabled' => 'force', // force against localhost check - 'headers' => [], // no default headers to test covage from sendCSPHeader - ]); - $sec->load(); - $this->expectExceptionMessageMatches( - '/^Headers already sent!*$/' - ); - $this->assertFalse($sec->sendHeaders()); + if (F::exists($this->json) && ! F::exists($this->yaml)) { + $json = Json::decode(F::read($this->json)); + F::write($this->yaml, Yaml::encode($json)); + } } - public function testSendHeadersFull() + public function after(): void { - $sec = new Bnomei\SecurityHeaders([ - 'enabled' => 'force', // force against localhost check - ]); - $sec->load(); - $this->expectExceptionMessageMatches( - '/^Cannot modify header information - headers already sent by.*$/' - ); - $this->assertTrue($sec->sendHeaders()); + F::remove($this->apache); + F::remove($this->nginx); } - public function testNonces() + public static function make(array $args = []): self { - $sec = new Bnomei\SecurityHeaders(); - $n = $sec->setNonce('test'); - $this->assertMatchesRegularExpression('/^(.){54}==$/', $n); - $this->assertEquals($n, $sec->getNonce('test')); + return new self(...(count($args) === 0 ? static::PATHS : $args)); } } + +beforeEach(function () { + TestHelper::make()->before(); +}); + +afterEach(function () { + TestHelper::make()->after(); +}); + +test('construct', function () { + $sec = new Bnomei\SecurityHeaders; + expect($sec)->toBeInstanceOf(SecurityHeaders::class); +}); + +test('options', function () { + $sec = new Bnomei\SecurityHeaders; + expect($sec->option())->toBeArray(); + expect($sec->option())->toHaveCount(8); + + expect($sec->option('debug'))->toBeTrue(); + + // config "force" + $sec = new Bnomei\SecurityHeaders([ + 'debug' => true, + 'enabled' => function () { + return false; + }, + ]); + expect($sec->option('debug'))->toBeTrue(); + expect($sec->option('enabled'))->toBeFalse(); +}); + +test('csp', function () { + $sec = new Bnomei\SecurityHeaders; + $builder = $sec->csp(); + expect($builder)->toBeInstanceOf(CSPBuilder::class); + expect($sec->csp())->toEqual($builder); +}); + +test('load', function () { + $sec = new Bnomei\SecurityHeaders; + $builder = $sec->load([]); + expect($builder)->toBeInstanceOf(CSPBuilder::class); + + $builder = $sec->load(TestHelper::PATHS['json']); + expect($builder)->toBeInstanceOf(CSPBuilder::class); + + $builder = $sec->load(TestHelper::PATHS['yaml']); + expect($builder)->toBeInstanceOf(CSPBuilder::class); + + $builder = $sec->load(Json::decode(F::read(TestHelper::PATHS['json']))); + expect($builder)->toBeInstanceOf(CSPBuilder::class); +}); + +test('apply setter', function () { + $sec = new Bnomei\SecurityHeaders([ + 'setter' => function (SecurityHeaders $instance) { + $instance->saveApache(TestHelper::PATHS['apache']); + }, + ]); + $sec->load(); + $sec->applySetter(); + expect(F::exists(TestHelper::PATHS['apache']))->toBeTrue(); +}); + +test('save', function () { + $sec = SecurityHeaders::singleton(); + expect($sec->saveApache(TestHelper::PATHS['apache']))->toBeTrue() + ->and($sec->saveNginx(TestHelper::PATHS['nginx']))->toBeTrue(); +}); + +test('singleton', function () { + $sec = SecurityHeaders::singleton(); + expect($sec)->toBeInstanceOf(SecurityHeaders::class); +}); + +test('send headers disabled', function () { + $sec = new Bnomei\SecurityHeaders([ + 'enabled' => false, // force against localhost check + ]); + expect($sec->sendHeaders())->toBeFalse(); +}); + +test('send headers full', function () { + $sec = new Bnomei\SecurityHeaders([ + 'enabled' => true, // force against localhost check + ]); + expect($sec->sendHeaders())->toBeTrue(); +}); + +test('nonces', function () { + $sec = new Bnomei\SecurityHeaders; + $n = $sec->setNonce('test'); + expect($n)->toMatch('/^(.){54}==$/') + ->and($sec->getNonce('test'))->toEqual($n); +}); diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index 7502ed9..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,7 +0,0 @@ -render(); diff --git a/tests/test-builder-config.json b/tests/fixtures/securityheaders.json similarity index 100% rename from tests/test-builder-config.json rename to tests/fixtures/securityheaders.json diff --git a/tests/test-builder-config.yml b/tests/fixtures/securityheaders.yml similarity index 100% rename from tests/test-builder-config.yml rename to tests/fixtures/securityheaders.yml diff --git a/tests/index.php b/tests/index.php index 5039cae..01a3ee0 100644 --- a/tests/index.php +++ b/tests/index.php @@ -1,5 +1,7 @@ render(); +$kirby = new Kirby; + +echo $kirby->render(); diff --git a/tests/site/config/config.php b/tests/site/config/config.php index d2aaad0..5f1327c 100644 --- a/tests/site/config/config.php +++ b/tests/site/config/config.php @@ -2,9 +2,10 @@ return [ 'debug' => true, - 'bnomei.securityheaders.enabled' => 'force', // force even on http localhost + + 'bnomei.securityheaders.enabled' => true, // force even on http localhost 'bnomei.securityheaders.loader' => function () { - return kirby()->roots()->site() . '/loader-test.json'; + return kirby()->roots()->config().'/csp.json'; }, ]; diff --git a/tests/site/loader-test.json b/tests/site/config/csp.json similarity index 100% rename from tests/site/loader-test.json rename to tests/site/config/csp.json diff --git a/tests/site/plugins/kirby3-security-headers/index.php b/tests/site/plugins/kirby3-security-headers/index.php index 7e74d8b..c0662bf 100644 --- a/tests/site/plugins/kirby3-security-headers/index.php +++ b/tests/site/plugins/kirby3-security-headers/index.php @@ -1,3 +1,3 @@ $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php', 'Kirby\\ComposerInstaller\\Plugin' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php', 'Kirby\\ComposerInstaller\\PluginInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php', + 'Opis\\JsonSchema\\CompliantValidator' => $vendorDir . '/opis/json-schema/src/CompliantValidator.php', + 'Opis\\JsonSchema\\ContentEncoding' => $vendorDir . '/opis/json-schema/src/ContentEncoding.php', + 'Opis\\JsonSchema\\ContentMediaType' => $vendorDir . '/opis/json-schema/src/ContentMediaType.php', + 'Opis\\JsonSchema\\Errors\\CustomError' => $vendorDir . '/opis/json-schema/src/Errors/CustomError.php', + 'Opis\\JsonSchema\\Errors\\ErrorContainer' => $vendorDir . '/opis/json-schema/src/Errors/ErrorContainer.php', + 'Opis\\JsonSchema\\Errors\\ErrorFormatter' => $vendorDir . '/opis/json-schema/src/Errors/ErrorFormatter.php', + 'Opis\\JsonSchema\\Errors\\ValidationError' => $vendorDir . '/opis/json-schema/src/Errors/ValidationError.php', + 'Opis\\JsonSchema\\Exceptions\\DuplicateSchemaIdException' => $vendorDir . '/opis/json-schema/src/Exceptions/DuplicateSchemaIdException.php', + 'Opis\\JsonSchema\\Exceptions\\InvalidKeywordException' => $vendorDir . '/opis/json-schema/src/Exceptions/InvalidKeywordException.php', + 'Opis\\JsonSchema\\Exceptions\\InvalidPragmaException' => $vendorDir . '/opis/json-schema/src/Exceptions/InvalidPragmaException.php', + 'Opis\\JsonSchema\\Exceptions\\ParseException' => $vendorDir . '/opis/json-schema/src/Exceptions/ParseException.php', + 'Opis\\JsonSchema\\Exceptions\\SchemaException' => $vendorDir . '/opis/json-schema/src/Exceptions/SchemaException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedContentEncodingException' => $vendorDir . '/opis/json-schema/src/Exceptions/UnresolvedContentEncodingException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedContentMediaTypeException' => $vendorDir . '/opis/json-schema/src/Exceptions/UnresolvedContentMediaTypeException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedException' => $vendorDir . '/opis/json-schema/src/Exceptions/UnresolvedException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedFilterException' => $vendorDir . '/opis/json-schema/src/Exceptions/UnresolvedFilterException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedReferenceException' => $vendorDir . '/opis/json-schema/src/Exceptions/UnresolvedReferenceException.php', + 'Opis\\JsonSchema\\Filter' => $vendorDir . '/opis/json-schema/src/Filter.php', + 'Opis\\JsonSchema\\Filters\\CommonFilters' => $vendorDir . '/opis/json-schema/src/Filters/CommonFilters.php', + 'Opis\\JsonSchema\\Filters\\DataExistsFilter' => $vendorDir . '/opis/json-schema/src/Filters/DataExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\DateTimeFilters' => $vendorDir . '/opis/json-schema/src/Filters/DateTimeFilters.php', + 'Opis\\JsonSchema\\Filters\\FilterExistsFilter' => $vendorDir . '/opis/json-schema/src/Filters/FilterExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\FormatExistsFilter' => $vendorDir . '/opis/json-schema/src/Filters/FormatExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\GlobalVarExistsFilter' => $vendorDir . '/opis/json-schema/src/Filters/GlobalVarExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\SchemaExistsFilter' => $vendorDir . '/opis/json-schema/src/Filters/SchemaExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\SlotExistsFilter' => $vendorDir . '/opis/json-schema/src/Filters/SlotExistsFilter.php', + 'Opis\\JsonSchema\\Format' => $vendorDir . '/opis/json-schema/src/Format.php', + 'Opis\\JsonSchema\\Formats\\DateTimeFormats' => $vendorDir . '/opis/json-schema/src/Formats/DateTimeFormats.php', + 'Opis\\JsonSchema\\Formats\\IriFormats' => $vendorDir . '/opis/json-schema/src/Formats/IriFormats.php', + 'Opis\\JsonSchema\\Formats\\MiscFormats' => $vendorDir . '/opis/json-schema/src/Formats/MiscFormats.php', + 'Opis\\JsonSchema\\Formats\\UriFormats' => $vendorDir . '/opis/json-schema/src/Formats/UriFormats.php', + 'Opis\\JsonSchema\\Helper' => $vendorDir . '/opis/json-schema/src/Helper.php', + 'Opis\\JsonSchema\\Info\\DataInfo' => $vendorDir . '/opis/json-schema/src/Info/DataInfo.php', + 'Opis\\JsonSchema\\Info\\SchemaInfo' => $vendorDir . '/opis/json-schema/src/Info/SchemaInfo.php', + 'Opis\\JsonSchema\\JsonPointer' => $vendorDir . '/opis/json-schema/src/JsonPointer.php', + 'Opis\\JsonSchema\\Keyword' => $vendorDir . '/opis/json-schema/src/Keyword.php', + 'Opis\\JsonSchema\\KeywordValidator' => $vendorDir . '/opis/json-schema/src/KeywordValidator.php', + 'Opis\\JsonSchema\\KeywordValidators\\AbstractKeywordValidator' => $vendorDir . '/opis/json-schema/src/KeywordValidators/AbstractKeywordValidator.php', + 'Opis\\JsonSchema\\KeywordValidators\\CallbackKeywordValidator' => $vendorDir . '/opis/json-schema/src/KeywordValidators/CallbackKeywordValidator.php', + 'Opis\\JsonSchema\\KeywordValidators\\PragmaKeywordValidator' => $vendorDir . '/opis/json-schema/src/KeywordValidators/PragmaKeywordValidator.php', + 'Opis\\JsonSchema\\Keywords\\AbstractRefKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/AbstractRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\AdditionalItemsKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/AdditionalItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\AdditionalPropertiesKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/AdditionalPropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\AllOfKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/AllOfKeyword.php', + 'Opis\\JsonSchema\\Keywords\\AnyOfKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/AnyOfKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ConstDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ConstDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ConstKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ConstKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ContainsKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ContainsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ContentEncodingKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ContentEncodingKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ContentMediaTypeKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ContentMediaTypeKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ContentSchemaKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ContentSchemaKeyword.php', + 'Opis\\JsonSchema\\Keywords\\DefaultKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/DefaultKeyword.php', + 'Opis\\JsonSchema\\Keywords\\DependenciesKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/DependenciesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\DependentRequiredKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/DependentRequiredKeyword.php', + 'Opis\\JsonSchema\\Keywords\\DependentSchemasKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/DependentSchemasKeyword.php', + 'Opis\\JsonSchema\\Keywords\\EnumDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/EnumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\EnumKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/EnumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ErrorTrait' => $vendorDir . '/opis/json-schema/src/Keywords/ErrorTrait.php', + 'Opis\\JsonSchema\\Keywords\\ExclusiveMaximumDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ExclusiveMaximumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ExclusiveMaximumKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ExclusiveMaximumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ExclusiveMinimumDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ExclusiveMinimumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ExclusiveMinimumKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ExclusiveMinimumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\FiltersKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/FiltersKeyword.php', + 'Opis\\JsonSchema\\Keywords\\FormatDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/FormatDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\FormatKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/FormatKeyword.php', + 'Opis\\JsonSchema\\Keywords\\IfThenElseKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/IfThenElseKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ItemsKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/ItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\IterableDataValidationTrait' => $vendorDir . '/opis/json-schema/src/Keywords/IterableDataValidationTrait.php', + 'Opis\\JsonSchema\\Keywords\\MaxItemsDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MaxItemsDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxItemsKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MaxItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxLengthDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MaxLengthDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxLengthKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MaxLengthKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxPropertiesDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MaxPropertiesDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxPropertiesKeywords' => $vendorDir . '/opis/json-schema/src/Keywords/MaxPropertiesKeywords.php', + 'Opis\\JsonSchema\\Keywords\\MaximumDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MaximumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaximumKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MaximumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinItemsDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MinItemsDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinItemsKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MinItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinLengthDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MinLengthDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinLengthKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MinLengthKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinPropertiesDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MinPropertiesDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinPropertiesKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MinPropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinimumDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MinimumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinimumKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MinimumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MultipleOfDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MultipleOfDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MultipleOfKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/MultipleOfKeyword.php', + 'Opis\\JsonSchema\\Keywords\\NotKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/NotKeyword.php', + 'Opis\\JsonSchema\\Keywords\\OfTrait' => $vendorDir . '/opis/json-schema/src/Keywords/OfTrait.php', + 'Opis\\JsonSchema\\Keywords\\OneOfKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/OneOfKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PatternDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/PatternDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PatternKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/PatternKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PatternPropertiesKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/PatternPropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PointerRefKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/PointerRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PropertiesKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/PropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PropertyNamesKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/PropertyNamesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\RecursiveRefKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/RecursiveRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\RequiredDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/RequiredDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\RequiredKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/RequiredKeyword.php', + 'Opis\\JsonSchema\\Keywords\\SlotsKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/SlotsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\TemplateRefKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/TemplateRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\TypeKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/TypeKeyword.php', + 'Opis\\JsonSchema\\Keywords\\URIRefKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/URIRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\UnevaluatedItemsKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/UnevaluatedItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\UnevaluatedPropertiesKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/UnevaluatedPropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\UniqueItemsDataKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/UniqueItemsDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\UniqueItemsKeyword' => $vendorDir . '/opis/json-schema/src/Keywords/UniqueItemsKeyword.php', + 'Opis\\JsonSchema\\Parsers\\DataKeywordTrait' => $vendorDir . '/opis/json-schema/src/Parsers/DataKeywordTrait.php', + 'Opis\\JsonSchema\\Parsers\\DefaultVocabulary' => $vendorDir . '/opis/json-schema/src/Parsers/DefaultVocabulary.php', + 'Opis\\JsonSchema\\Parsers\\Draft' => $vendorDir . '/opis/json-schema/src/Parsers/Draft.php', + 'Opis\\JsonSchema\\Parsers\\DraftOptionTrait' => $vendorDir . '/opis/json-schema/src/Parsers/DraftOptionTrait.php', + 'Opis\\JsonSchema\\Parsers\\Drafts\\Draft06' => $vendorDir . '/opis/json-schema/src/Parsers/Drafts/Draft06.php', + 'Opis\\JsonSchema\\Parsers\\Drafts\\Draft07' => $vendorDir . '/opis/json-schema/src/Parsers/Drafts/Draft07.php', + 'Opis\\JsonSchema\\Parsers\\Drafts\\Draft201909' => $vendorDir . '/opis/json-schema/src/Parsers/Drafts/Draft201909.php', + 'Opis\\JsonSchema\\Parsers\\Drafts\\Draft202012' => $vendorDir . '/opis/json-schema/src/Parsers/Drafts/Draft202012.php', + 'Opis\\JsonSchema\\Parsers\\KeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/KeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\KeywordParserTrait' => $vendorDir . '/opis/json-schema/src/Parsers/KeywordParserTrait.php', + 'Opis\\JsonSchema\\Parsers\\KeywordValidatorParser' => $vendorDir . '/opis/json-schema/src/Parsers/KeywordValidatorParser.php', + 'Opis\\JsonSchema\\Parsers\\KeywordValidators\\PragmaKeywordValidatorParser' => $vendorDir . '/opis/json-schema/src/Parsers/KeywordValidators/PragmaKeywordValidatorParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\AdditionalItemsKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/AdditionalItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\AdditionalPropertiesKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/AdditionalPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\AllOfKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/AllOfKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\AnyOfKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/AnyOfKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ConstKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/ConstKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ContainsKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/ContainsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ContentEncodingKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/ContentEncodingKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ContentMediaTypeKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/ContentMediaTypeKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ContentSchemaKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/ContentSchemaKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\DefaultKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/DefaultKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\DependenciesKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/DependenciesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\DependentRequiredKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/DependentRequiredKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\DependentSchemasKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/DependentSchemasKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\EnumKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/EnumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ExclusiveMaximumKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/ExclusiveMaximumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ExclusiveMinimumKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/ExclusiveMinimumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\FiltersKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/FiltersKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\FormatKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/FormatKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\IfThenElseKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/IfThenElseKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ItemsKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/ItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MaxItemsKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MaxItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MaxLengthKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MaxLengthKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MaxPropertiesKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MaxPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MaximumKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MaximumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MinItemsKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MinItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MinLengthKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MinLengthKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MinPropertiesKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MinPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MinimumKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MinimumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MultipleOfKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/MultipleOfKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\NotKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/NotKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\OneOfKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/OneOfKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\PatternKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/PatternKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\PatternPropertiesKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/PatternPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\PropertiesKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/PropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\PropertyNamesKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/PropertyNamesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\RefKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/RefKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\RequiredKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/RequiredKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\SlotsKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/SlotsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\TypeKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/TypeKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\UnevaluatedItemsKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/UnevaluatedItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\UnevaluatedPropertiesKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/UnevaluatedPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\UniqueItemsKeywordParser' => $vendorDir . '/opis/json-schema/src/Parsers/Keywords/UniqueItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\PragmaParser' => $vendorDir . '/opis/json-schema/src/Parsers/PragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\Pragmas\\CastPragmaParser' => $vendorDir . '/opis/json-schema/src/Parsers/Pragmas/CastPragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\Pragmas\\GlobalsPragmaParser' => $vendorDir . '/opis/json-schema/src/Parsers/Pragmas/GlobalsPragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\Pragmas\\MaxErrorsPragmaParser' => $vendorDir . '/opis/json-schema/src/Parsers/Pragmas/MaxErrorsPragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\Pragmas\\SlotsPragmaParser' => $vendorDir . '/opis/json-schema/src/Parsers/Pragmas/SlotsPragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\ResolverTrait' => $vendorDir . '/opis/json-schema/src/Parsers/ResolverTrait.php', + 'Opis\\JsonSchema\\Parsers\\SchemaParser' => $vendorDir . '/opis/json-schema/src/Parsers/SchemaParser.php', + 'Opis\\JsonSchema\\Parsers\\VariablesTrait' => $vendorDir . '/opis/json-schema/src/Parsers/VariablesTrait.php', + 'Opis\\JsonSchema\\Parsers\\Vocabulary' => $vendorDir . '/opis/json-schema/src/Parsers/Vocabulary.php', + 'Opis\\JsonSchema\\Pragma' => $vendorDir . '/opis/json-schema/src/Pragma.php', + 'Opis\\JsonSchema\\Pragmas\\CastPragma' => $vendorDir . '/opis/json-schema/src/Pragmas/CastPragma.php', + 'Opis\\JsonSchema\\Pragmas\\GlobalsPragma' => $vendorDir . '/opis/json-schema/src/Pragmas/GlobalsPragma.php', + 'Opis\\JsonSchema\\Pragmas\\MaxErrorsPragma' => $vendorDir . '/opis/json-schema/src/Pragmas/MaxErrorsPragma.php', + 'Opis\\JsonSchema\\Pragmas\\SlotsPragma' => $vendorDir . '/opis/json-schema/src/Pragmas/SlotsPragma.php', + 'Opis\\JsonSchema\\Resolvers\\ContentEncodingResolver' => $vendorDir . '/opis/json-schema/src/Resolvers/ContentEncodingResolver.php', + 'Opis\\JsonSchema\\Resolvers\\ContentMediaTypeResolver' => $vendorDir . '/opis/json-schema/src/Resolvers/ContentMediaTypeResolver.php', + 'Opis\\JsonSchema\\Resolvers\\FilterResolver' => $vendorDir . '/opis/json-schema/src/Resolvers/FilterResolver.php', + 'Opis\\JsonSchema\\Resolvers\\FormatResolver' => $vendorDir . '/opis/json-schema/src/Resolvers/FormatResolver.php', + 'Opis\\JsonSchema\\Resolvers\\SchemaResolver' => $vendorDir . '/opis/json-schema/src/Resolvers/SchemaResolver.php', + 'Opis\\JsonSchema\\Schema' => $vendorDir . '/opis/json-schema/src/Schema.php', + 'Opis\\JsonSchema\\SchemaLoader' => $vendorDir . '/opis/json-schema/src/SchemaLoader.php', + 'Opis\\JsonSchema\\SchemaValidator' => $vendorDir . '/opis/json-schema/src/SchemaValidator.php', + 'Opis\\JsonSchema\\Schemas\\AbstractSchema' => $vendorDir . '/opis/json-schema/src/Schemas/AbstractSchema.php', + 'Opis\\JsonSchema\\Schemas\\BooleanSchema' => $vendorDir . '/opis/json-schema/src/Schemas/BooleanSchema.php', + 'Opis\\JsonSchema\\Schemas\\EmptySchema' => $vendorDir . '/opis/json-schema/src/Schemas/EmptySchema.php', + 'Opis\\JsonSchema\\Schemas\\ExceptionSchema' => $vendorDir . '/opis/json-schema/src/Schemas/ExceptionSchema.php', + 'Opis\\JsonSchema\\Schemas\\LazySchema' => $vendorDir . '/opis/json-schema/src/Schemas/LazySchema.php', + 'Opis\\JsonSchema\\Schemas\\ObjectSchema' => $vendorDir . '/opis/json-schema/src/Schemas/ObjectSchema.php', + 'Opis\\JsonSchema\\Uri' => $vendorDir . '/opis/json-schema/src/Uri.php', + 'Opis\\JsonSchema\\ValidationContext' => $vendorDir . '/opis/json-schema/src/ValidationContext.php', + 'Opis\\JsonSchema\\ValidationResult' => $vendorDir . '/opis/json-schema/src/ValidationResult.php', + 'Opis\\JsonSchema\\Validator' => $vendorDir . '/opis/json-schema/src/Validator.php', + 'Opis\\JsonSchema\\Variables' => $vendorDir . '/opis/json-schema/src/Variables.php', + 'Opis\\JsonSchema\\Variables\\RefVariablesContainer' => $vendorDir . '/opis/json-schema/src/Variables/RefVariablesContainer.php', + 'Opis\\JsonSchema\\Variables\\VariablesContainer' => $vendorDir . '/opis/json-schema/src/Variables/VariablesContainer.php', + 'Opis\\String\\Exception\\InvalidCodePointException' => $vendorDir . '/opis/string/src/Exception/InvalidCodePointException.php', + 'Opis\\String\\Exception\\InvalidStringException' => $vendorDir . '/opis/string/src/Exception/InvalidStringException.php', + 'Opis\\String\\Exception\\UnicodeException' => $vendorDir . '/opis/string/src/Exception/UnicodeException.php', + 'Opis\\String\\UnicodeString' => $vendorDir . '/opis/string/src/UnicodeString.php', + 'Opis\\Uri\\Punycode' => $vendorDir . '/opis/uri/src/Punycode.php', + 'Opis\\Uri\\PunycodeException' => $vendorDir . '/opis/uri/src/PunycodeException.php', + 'Opis\\Uri\\Uri' => $vendorDir . '/opis/uri/src/Uri.php', + 'Opis\\Uri\\UriTemplate' => $vendorDir . '/opis/uri/src/UriTemplate.php', 'ParagonIE\\CSPBuilder\\CSPBuilder' => $vendorDir . '/paragonie/csp-builder/src/CSPBuilder.php', 'ParagonIE\\ConstantTime\\Base32' => $vendorDir . '/paragonie/constant_time_encoding/src/Base32.php', 'ParagonIE\\ConstantTime\\Base32Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Base32Hex.php', diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 78a2d49..5db02c5 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -9,6 +9,9 @@ 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), 'ParagonIE\\CSPBuilder\\' => array($vendorDir . '/paragonie/csp-builder/src'), + 'Opis\\Uri\\' => array($vendorDir . '/opis/uri/src'), + 'Opis\\String\\' => array($vendorDir . '/opis/string/src'), + 'Opis\\JsonSchema\\' => array($vendorDir . '/opis/json-schema/src'), 'Kirby\\' => array($vendorDir . '/getkirby/composer-installer/src'), 'Bnomei\\' => array($baseDir . '/classes'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 5ce08a8..1022e93 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit18addf989686478ebf461db052d40419 +class ComposerAutoloaderInit137ea556a6733e83dd49c3d70017ef0a { private static $loader; @@ -24,12 +24,12 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit18addf989686478ebf461db052d40419', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit137ea556a6733e83dd49c3d70017ef0a', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit18addf989686478ebf461db052d40419', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit137ea556a6733e83dd49c3d70017ef0a', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit18addf989686478ebf461db052d40419::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit137ea556a6733e83dd49c3d70017ef0a::getInitializer($loader)); $loader->register(true); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 94410e5..f9da48d 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit18addf989686478ebf461db052d40419 +class ComposerStaticInit137ea556a6733e83dd49c3d70017ef0a { public static $prefixLengthsPsr4 = array ( 'P' => @@ -13,6 +13,12 @@ class ComposerStaticInit18addf989686478ebf461db052d40419 'ParagonIE\\ConstantTime\\' => 23, 'ParagonIE\\CSPBuilder\\' => 21, ), + 'O' => + array ( + 'Opis\\Uri\\' => 9, + 'Opis\\String\\' => 12, + 'Opis\\JsonSchema\\' => 16, + ), 'K' => array ( 'Kirby\\' => 6, @@ -36,6 +42,18 @@ class ComposerStaticInit18addf989686478ebf461db052d40419 array ( 0 => __DIR__ . '/..' . '/paragonie/csp-builder/src', ), + 'Opis\\Uri\\' => + array ( + 0 => __DIR__ . '/..' . '/opis/uri/src', + ), + 'Opis\\String\\' => + array ( + 0 => __DIR__ . '/..' . '/opis/string/src', + ), + 'Opis\\JsonSchema\\' => + array ( + 0 => __DIR__ . '/..' . '/opis/json-schema/src', + ), 'Kirby\\' => array ( 0 => __DIR__ . '/..' . '/getkirby/composer-installer/src', @@ -53,6 +71,209 @@ class ComposerStaticInit18addf989686478ebf461db052d40419 'Kirby\\ComposerInstaller\\Installer' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php', 'Kirby\\ComposerInstaller\\Plugin' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php', 'Kirby\\ComposerInstaller\\PluginInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php', + 'Opis\\JsonSchema\\CompliantValidator' => __DIR__ . '/..' . '/opis/json-schema/src/CompliantValidator.php', + 'Opis\\JsonSchema\\ContentEncoding' => __DIR__ . '/..' . '/opis/json-schema/src/ContentEncoding.php', + 'Opis\\JsonSchema\\ContentMediaType' => __DIR__ . '/..' . '/opis/json-schema/src/ContentMediaType.php', + 'Opis\\JsonSchema\\Errors\\CustomError' => __DIR__ . '/..' . '/opis/json-schema/src/Errors/CustomError.php', + 'Opis\\JsonSchema\\Errors\\ErrorContainer' => __DIR__ . '/..' . '/opis/json-schema/src/Errors/ErrorContainer.php', + 'Opis\\JsonSchema\\Errors\\ErrorFormatter' => __DIR__ . '/..' . '/opis/json-schema/src/Errors/ErrorFormatter.php', + 'Opis\\JsonSchema\\Errors\\ValidationError' => __DIR__ . '/..' . '/opis/json-schema/src/Errors/ValidationError.php', + 'Opis\\JsonSchema\\Exceptions\\DuplicateSchemaIdException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/DuplicateSchemaIdException.php', + 'Opis\\JsonSchema\\Exceptions\\InvalidKeywordException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/InvalidKeywordException.php', + 'Opis\\JsonSchema\\Exceptions\\InvalidPragmaException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/InvalidPragmaException.php', + 'Opis\\JsonSchema\\Exceptions\\ParseException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/ParseException.php', + 'Opis\\JsonSchema\\Exceptions\\SchemaException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/SchemaException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedContentEncodingException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/UnresolvedContentEncodingException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedContentMediaTypeException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/UnresolvedContentMediaTypeException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/UnresolvedException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedFilterException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/UnresolvedFilterException.php', + 'Opis\\JsonSchema\\Exceptions\\UnresolvedReferenceException' => __DIR__ . '/..' . '/opis/json-schema/src/Exceptions/UnresolvedReferenceException.php', + 'Opis\\JsonSchema\\Filter' => __DIR__ . '/..' . '/opis/json-schema/src/Filter.php', + 'Opis\\JsonSchema\\Filters\\CommonFilters' => __DIR__ . '/..' . '/opis/json-schema/src/Filters/CommonFilters.php', + 'Opis\\JsonSchema\\Filters\\DataExistsFilter' => __DIR__ . '/..' . '/opis/json-schema/src/Filters/DataExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\DateTimeFilters' => __DIR__ . '/..' . '/opis/json-schema/src/Filters/DateTimeFilters.php', + 'Opis\\JsonSchema\\Filters\\FilterExistsFilter' => __DIR__ . '/..' . '/opis/json-schema/src/Filters/FilterExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\FormatExistsFilter' => __DIR__ . '/..' . '/opis/json-schema/src/Filters/FormatExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\GlobalVarExistsFilter' => __DIR__ . '/..' . '/opis/json-schema/src/Filters/GlobalVarExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\SchemaExistsFilter' => __DIR__ . '/..' . '/opis/json-schema/src/Filters/SchemaExistsFilter.php', + 'Opis\\JsonSchema\\Filters\\SlotExistsFilter' => __DIR__ . '/..' . '/opis/json-schema/src/Filters/SlotExistsFilter.php', + 'Opis\\JsonSchema\\Format' => __DIR__ . '/..' . '/opis/json-schema/src/Format.php', + 'Opis\\JsonSchema\\Formats\\DateTimeFormats' => __DIR__ . '/..' . '/opis/json-schema/src/Formats/DateTimeFormats.php', + 'Opis\\JsonSchema\\Formats\\IriFormats' => __DIR__ . '/..' . '/opis/json-schema/src/Formats/IriFormats.php', + 'Opis\\JsonSchema\\Formats\\MiscFormats' => __DIR__ . '/..' . '/opis/json-schema/src/Formats/MiscFormats.php', + 'Opis\\JsonSchema\\Formats\\UriFormats' => __DIR__ . '/..' . '/opis/json-schema/src/Formats/UriFormats.php', + 'Opis\\JsonSchema\\Helper' => __DIR__ . '/..' . '/opis/json-schema/src/Helper.php', + 'Opis\\JsonSchema\\Info\\DataInfo' => __DIR__ . '/..' . '/opis/json-schema/src/Info/DataInfo.php', + 'Opis\\JsonSchema\\Info\\SchemaInfo' => __DIR__ . '/..' . '/opis/json-schema/src/Info/SchemaInfo.php', + 'Opis\\JsonSchema\\JsonPointer' => __DIR__ . '/..' . '/opis/json-schema/src/JsonPointer.php', + 'Opis\\JsonSchema\\Keyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keyword.php', + 'Opis\\JsonSchema\\KeywordValidator' => __DIR__ . '/..' . '/opis/json-schema/src/KeywordValidator.php', + 'Opis\\JsonSchema\\KeywordValidators\\AbstractKeywordValidator' => __DIR__ . '/..' . '/opis/json-schema/src/KeywordValidators/AbstractKeywordValidator.php', + 'Opis\\JsonSchema\\KeywordValidators\\CallbackKeywordValidator' => __DIR__ . '/..' . '/opis/json-schema/src/KeywordValidators/CallbackKeywordValidator.php', + 'Opis\\JsonSchema\\KeywordValidators\\PragmaKeywordValidator' => __DIR__ . '/..' . '/opis/json-schema/src/KeywordValidators/PragmaKeywordValidator.php', + 'Opis\\JsonSchema\\Keywords\\AbstractRefKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/AbstractRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\AdditionalItemsKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/AdditionalItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\AdditionalPropertiesKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/AdditionalPropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\AllOfKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/AllOfKeyword.php', + 'Opis\\JsonSchema\\Keywords\\AnyOfKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/AnyOfKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ConstDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ConstDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ConstKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ConstKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ContainsKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ContainsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ContentEncodingKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ContentEncodingKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ContentMediaTypeKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ContentMediaTypeKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ContentSchemaKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ContentSchemaKeyword.php', + 'Opis\\JsonSchema\\Keywords\\DefaultKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/DefaultKeyword.php', + 'Opis\\JsonSchema\\Keywords\\DependenciesKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/DependenciesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\DependentRequiredKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/DependentRequiredKeyword.php', + 'Opis\\JsonSchema\\Keywords\\DependentSchemasKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/DependentSchemasKeyword.php', + 'Opis\\JsonSchema\\Keywords\\EnumDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/EnumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\EnumKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/EnumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ErrorTrait' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ErrorTrait.php', + 'Opis\\JsonSchema\\Keywords\\ExclusiveMaximumDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ExclusiveMaximumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ExclusiveMaximumKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ExclusiveMaximumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ExclusiveMinimumDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ExclusiveMinimumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ExclusiveMinimumKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ExclusiveMinimumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\FiltersKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/FiltersKeyword.php', + 'Opis\\JsonSchema\\Keywords\\FormatDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/FormatDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\FormatKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/FormatKeyword.php', + 'Opis\\JsonSchema\\Keywords\\IfThenElseKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/IfThenElseKeyword.php', + 'Opis\\JsonSchema\\Keywords\\ItemsKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/ItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\IterableDataValidationTrait' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/IterableDataValidationTrait.php', + 'Opis\\JsonSchema\\Keywords\\MaxItemsDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MaxItemsDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxItemsKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MaxItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxLengthDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MaxLengthDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxLengthKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MaxLengthKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxPropertiesDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MaxPropertiesDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaxPropertiesKeywords' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MaxPropertiesKeywords.php', + 'Opis\\JsonSchema\\Keywords\\MaximumDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MaximumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MaximumKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MaximumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinItemsDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MinItemsDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinItemsKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MinItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinLengthDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MinLengthDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinLengthKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MinLengthKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinPropertiesDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MinPropertiesDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinPropertiesKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MinPropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinimumDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MinimumDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MinimumKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MinimumKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MultipleOfDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MultipleOfDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\MultipleOfKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/MultipleOfKeyword.php', + 'Opis\\JsonSchema\\Keywords\\NotKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/NotKeyword.php', + 'Opis\\JsonSchema\\Keywords\\OfTrait' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/OfTrait.php', + 'Opis\\JsonSchema\\Keywords\\OneOfKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/OneOfKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PatternDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/PatternDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PatternKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/PatternKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PatternPropertiesKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/PatternPropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PointerRefKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/PointerRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PropertiesKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/PropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\PropertyNamesKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/PropertyNamesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\RecursiveRefKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/RecursiveRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\RequiredDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/RequiredDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\RequiredKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/RequiredKeyword.php', + 'Opis\\JsonSchema\\Keywords\\SlotsKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/SlotsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\TemplateRefKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/TemplateRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\TypeKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/TypeKeyword.php', + 'Opis\\JsonSchema\\Keywords\\URIRefKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/URIRefKeyword.php', + 'Opis\\JsonSchema\\Keywords\\UnevaluatedItemsKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/UnevaluatedItemsKeyword.php', + 'Opis\\JsonSchema\\Keywords\\UnevaluatedPropertiesKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/UnevaluatedPropertiesKeyword.php', + 'Opis\\JsonSchema\\Keywords\\UniqueItemsDataKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/UniqueItemsDataKeyword.php', + 'Opis\\JsonSchema\\Keywords\\UniqueItemsKeyword' => __DIR__ . '/..' . '/opis/json-schema/src/Keywords/UniqueItemsKeyword.php', + 'Opis\\JsonSchema\\Parsers\\DataKeywordTrait' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/DataKeywordTrait.php', + 'Opis\\JsonSchema\\Parsers\\DefaultVocabulary' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/DefaultVocabulary.php', + 'Opis\\JsonSchema\\Parsers\\Draft' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Draft.php', + 'Opis\\JsonSchema\\Parsers\\DraftOptionTrait' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/DraftOptionTrait.php', + 'Opis\\JsonSchema\\Parsers\\Drafts\\Draft06' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Drafts/Draft06.php', + 'Opis\\JsonSchema\\Parsers\\Drafts\\Draft07' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Drafts/Draft07.php', + 'Opis\\JsonSchema\\Parsers\\Drafts\\Draft201909' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Drafts/Draft201909.php', + 'Opis\\JsonSchema\\Parsers\\Drafts\\Draft202012' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Drafts/Draft202012.php', + 'Opis\\JsonSchema\\Parsers\\KeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/KeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\KeywordParserTrait' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/KeywordParserTrait.php', + 'Opis\\JsonSchema\\Parsers\\KeywordValidatorParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/KeywordValidatorParser.php', + 'Opis\\JsonSchema\\Parsers\\KeywordValidators\\PragmaKeywordValidatorParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/KeywordValidators/PragmaKeywordValidatorParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\AdditionalItemsKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/AdditionalItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\AdditionalPropertiesKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/AdditionalPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\AllOfKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/AllOfKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\AnyOfKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/AnyOfKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ConstKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/ConstKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ContainsKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/ContainsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ContentEncodingKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/ContentEncodingKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ContentMediaTypeKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/ContentMediaTypeKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ContentSchemaKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/ContentSchemaKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\DefaultKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/DefaultKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\DependenciesKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/DependenciesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\DependentRequiredKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/DependentRequiredKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\DependentSchemasKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/DependentSchemasKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\EnumKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/EnumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ExclusiveMaximumKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/ExclusiveMaximumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ExclusiveMinimumKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/ExclusiveMinimumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\FiltersKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/FiltersKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\FormatKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/FormatKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\IfThenElseKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/IfThenElseKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\ItemsKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/ItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MaxItemsKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MaxItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MaxLengthKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MaxLengthKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MaxPropertiesKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MaxPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MaximumKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MaximumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MinItemsKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MinItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MinLengthKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MinLengthKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MinPropertiesKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MinPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MinimumKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MinimumKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\MultipleOfKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/MultipleOfKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\NotKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/NotKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\OneOfKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/OneOfKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\PatternKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/PatternKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\PatternPropertiesKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/PatternPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\PropertiesKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/PropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\PropertyNamesKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/PropertyNamesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\RefKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/RefKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\RequiredKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/RequiredKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\SlotsKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/SlotsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\TypeKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/TypeKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\UnevaluatedItemsKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/UnevaluatedItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\UnevaluatedPropertiesKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/UnevaluatedPropertiesKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\Keywords\\UniqueItemsKeywordParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Keywords/UniqueItemsKeywordParser.php', + 'Opis\\JsonSchema\\Parsers\\PragmaParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/PragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\Pragmas\\CastPragmaParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Pragmas/CastPragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\Pragmas\\GlobalsPragmaParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Pragmas/GlobalsPragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\Pragmas\\MaxErrorsPragmaParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Pragmas/MaxErrorsPragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\Pragmas\\SlotsPragmaParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Pragmas/SlotsPragmaParser.php', + 'Opis\\JsonSchema\\Parsers\\ResolverTrait' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/ResolverTrait.php', + 'Opis\\JsonSchema\\Parsers\\SchemaParser' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/SchemaParser.php', + 'Opis\\JsonSchema\\Parsers\\VariablesTrait' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/VariablesTrait.php', + 'Opis\\JsonSchema\\Parsers\\Vocabulary' => __DIR__ . '/..' . '/opis/json-schema/src/Parsers/Vocabulary.php', + 'Opis\\JsonSchema\\Pragma' => __DIR__ . '/..' . '/opis/json-schema/src/Pragma.php', + 'Opis\\JsonSchema\\Pragmas\\CastPragma' => __DIR__ . '/..' . '/opis/json-schema/src/Pragmas/CastPragma.php', + 'Opis\\JsonSchema\\Pragmas\\GlobalsPragma' => __DIR__ . '/..' . '/opis/json-schema/src/Pragmas/GlobalsPragma.php', + 'Opis\\JsonSchema\\Pragmas\\MaxErrorsPragma' => __DIR__ . '/..' . '/opis/json-schema/src/Pragmas/MaxErrorsPragma.php', + 'Opis\\JsonSchema\\Pragmas\\SlotsPragma' => __DIR__ . '/..' . '/opis/json-schema/src/Pragmas/SlotsPragma.php', + 'Opis\\JsonSchema\\Resolvers\\ContentEncodingResolver' => __DIR__ . '/..' . '/opis/json-schema/src/Resolvers/ContentEncodingResolver.php', + 'Opis\\JsonSchema\\Resolvers\\ContentMediaTypeResolver' => __DIR__ . '/..' . '/opis/json-schema/src/Resolvers/ContentMediaTypeResolver.php', + 'Opis\\JsonSchema\\Resolvers\\FilterResolver' => __DIR__ . '/..' . '/opis/json-schema/src/Resolvers/FilterResolver.php', + 'Opis\\JsonSchema\\Resolvers\\FormatResolver' => __DIR__ . '/..' . '/opis/json-schema/src/Resolvers/FormatResolver.php', + 'Opis\\JsonSchema\\Resolvers\\SchemaResolver' => __DIR__ . '/..' . '/opis/json-schema/src/Resolvers/SchemaResolver.php', + 'Opis\\JsonSchema\\Schema' => __DIR__ . '/..' . '/opis/json-schema/src/Schema.php', + 'Opis\\JsonSchema\\SchemaLoader' => __DIR__ . '/..' . '/opis/json-schema/src/SchemaLoader.php', + 'Opis\\JsonSchema\\SchemaValidator' => __DIR__ . '/..' . '/opis/json-schema/src/SchemaValidator.php', + 'Opis\\JsonSchema\\Schemas\\AbstractSchema' => __DIR__ . '/..' . '/opis/json-schema/src/Schemas/AbstractSchema.php', + 'Opis\\JsonSchema\\Schemas\\BooleanSchema' => __DIR__ . '/..' . '/opis/json-schema/src/Schemas/BooleanSchema.php', + 'Opis\\JsonSchema\\Schemas\\EmptySchema' => __DIR__ . '/..' . '/opis/json-schema/src/Schemas/EmptySchema.php', + 'Opis\\JsonSchema\\Schemas\\ExceptionSchema' => __DIR__ . '/..' . '/opis/json-schema/src/Schemas/ExceptionSchema.php', + 'Opis\\JsonSchema\\Schemas\\LazySchema' => __DIR__ . '/..' . '/opis/json-schema/src/Schemas/LazySchema.php', + 'Opis\\JsonSchema\\Schemas\\ObjectSchema' => __DIR__ . '/..' . '/opis/json-schema/src/Schemas/ObjectSchema.php', + 'Opis\\JsonSchema\\Uri' => __DIR__ . '/..' . '/opis/json-schema/src/Uri.php', + 'Opis\\JsonSchema\\ValidationContext' => __DIR__ . '/..' . '/opis/json-schema/src/ValidationContext.php', + 'Opis\\JsonSchema\\ValidationResult' => __DIR__ . '/..' . '/opis/json-schema/src/ValidationResult.php', + 'Opis\\JsonSchema\\Validator' => __DIR__ . '/..' . '/opis/json-schema/src/Validator.php', + 'Opis\\JsonSchema\\Variables' => __DIR__ . '/..' . '/opis/json-schema/src/Variables.php', + 'Opis\\JsonSchema\\Variables\\RefVariablesContainer' => __DIR__ . '/..' . '/opis/json-schema/src/Variables/RefVariablesContainer.php', + 'Opis\\JsonSchema\\Variables\\VariablesContainer' => __DIR__ . '/..' . '/opis/json-schema/src/Variables/VariablesContainer.php', + 'Opis\\String\\Exception\\InvalidCodePointException' => __DIR__ . '/..' . '/opis/string/src/Exception/InvalidCodePointException.php', + 'Opis\\String\\Exception\\InvalidStringException' => __DIR__ . '/..' . '/opis/string/src/Exception/InvalidStringException.php', + 'Opis\\String\\Exception\\UnicodeException' => __DIR__ . '/..' . '/opis/string/src/Exception/UnicodeException.php', + 'Opis\\String\\UnicodeString' => __DIR__ . '/..' . '/opis/string/src/UnicodeString.php', + 'Opis\\Uri\\Punycode' => __DIR__ . '/..' . '/opis/uri/src/Punycode.php', + 'Opis\\Uri\\PunycodeException' => __DIR__ . '/..' . '/opis/uri/src/PunycodeException.php', + 'Opis\\Uri\\Uri' => __DIR__ . '/..' . '/opis/uri/src/Uri.php', + 'Opis\\Uri\\UriTemplate' => __DIR__ . '/..' . '/opis/uri/src/UriTemplate.php', 'ParagonIE\\CSPBuilder\\CSPBuilder' => __DIR__ . '/..' . '/paragonie/csp-builder/src/CSPBuilder.php', 'ParagonIE\\ConstantTime\\Base32' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base32.php', 'ParagonIE\\ConstantTime\\Base32Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base32Hex.php', @@ -77,9 +298,9 @@ class ComposerStaticInit18addf989686478ebf461db052d40419 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit18addf989686478ebf461db052d40419::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit18addf989686478ebf461db052d40419::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit18addf989686478ebf461db052d40419::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit137ea556a6733e83dd49c3d70017ef0a::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit137ea556a6733e83dd49c3d70017ef0a::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit137ea556a6733e83dd49c3d70017ef0a::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index ed86299..92da514 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,8 +1,8 @@ array( 'name' => 'bnomei/kirby3-security-headers', - 'pretty_version' => '4.0.0', - 'version' => '4.0.0.0', + 'pretty_version' => '5.0.0', + 'version' => '5.0.0.0', 'reference' => null, 'type' => 'kirby-plugin', 'install_path' => __DIR__ . '/../../', @@ -11,8 +11,8 @@ ), 'versions' => array( 'bnomei/kirby3-security-headers' => array( - 'pretty_version' => '4.0.0', - 'version' => '4.0.0.0', + 'pretty_version' => '5.0.0', + 'version' => '5.0.0.0', 'reference' => null, 'type' => 'kirby-plugin', 'install_path' => __DIR__ . '/../../', @@ -28,19 +28,46 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'opis/json-schema' => array( + 'pretty_version' => '2.3.0', + 'version' => '2.3.0.0', + 'reference' => 'c48df6d7089a45f01e1c82432348f2d5976f9bfb', + 'type' => 'library', + 'install_path' => __DIR__ . '/../opis/json-schema', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'opis/string' => array( + 'pretty_version' => '2.0.1', + 'version' => '2.0.1.0', + 'reference' => '9ebf1a1f873f502f6859d11210b25a4bf5d141e7', + 'type' => 'library', + 'install_path' => __DIR__ . '/../opis/string', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'opis/uri' => array( + 'pretty_version' => '1.1.0', + 'version' => '1.1.0.0', + 'reference' => '0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../opis/uri', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'paragonie/constant_time_encoding' => array( - 'pretty_version' => 'v2.6.3', - 'version' => '2.6.3.0', - 'reference' => '58c3f47f650c94ec05a151692652a868995d2938', + 'pretty_version' => 'v2.7.0', + 'version' => '2.7.0.0', + 'reference' => '52a0d99e69f56b9ec27ace92ba56897fe6993105', 'type' => 'library', 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', 'aliases' => array(), 'dev_requirement' => false, ), 'paragonie/csp-builder' => array( - 'pretty_version' => 'v2.9.0', - 'version' => '2.9.0.0', - 'reference' => '0c9592c3862eb8c6effcc0d31c7e4d8bbc0b3bae', + 'pretty_version' => 'v3.0.1', + 'version' => '3.0.1.0', + 'reference' => 'e2f9f177dd33311b7c16ea206488e0b10d1ea4d3', 'type' => 'library', 'install_path' => __DIR__ . '/../paragonie/csp-builder', 'aliases' => array(), diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index 4c3a5d6..d32d90c 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 80100)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80200)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/vendor/opis/json-schema/NOTICE b/vendor/opis/json-schema/NOTICE new file mode 100644 index 0000000..6ebfe37 --- /dev/null +++ b/vendor/opis/json-schema/NOTICE @@ -0,0 +1,9 @@ +Opis Json Schema +Copyright 2018-2021 Zindex Software + +This product includes software developed at +Zindex Software (http://zindex.software). + +This software was originally developed by Marius Sarca and Sorin Sarca +(Copyright 2017-2018). The copyright info was changed with the permission +of the original authors. diff --git a/vendor/opis/json-schema/autoload.php b/vendor/opis/json-schema/autoload.php new file mode 100644 index 0000000..649fab8 --- /dev/null +++ b/vendor/opis/json-schema/autoload.php @@ -0,0 +1,23 @@ + false, + 'allowFormats' => true, + 'allowMappers' => false, + 'allowTemplates' => false, + 'allowGlobals' => false, + 'allowDefaults' => false, + 'allowSlots' => false, + 'allowKeywordValidators' => false, + 'allowPragmas' => false, + 'allowDataKeyword' => false, + 'allowKeywordsAlongsideRef' => false, + 'allowUnevaluated' => true, + 'allowRelativeJsonPointerInRef' => false, + 'allowExclusiveMinMaxAsBool' => false, + 'keepDependenciesKeyword' => false, + 'keepAdditionalItemsKeyword' => false, + ]; + + public function __construct(?SchemaLoader $loader = null, int $max_errors = 1) + { + parent::__construct($loader, $max_errors); + + // Set parser options + $parser = $this->parser(); + foreach (static::COMPLIANT_OPTIONS as $name => $value) { + $parser->setOption($name, $value); + } + } +} diff --git a/vendor/opis/json-schema/src/ContentEncoding.php b/vendor/opis/json-schema/src/ContentEncoding.php new file mode 100644 index 0000000..3c6eb23 --- /dev/null +++ b/vendor/opis/json-schema/src/ContentEncoding.php @@ -0,0 +1,28 @@ +args = $args; + } + + public function getArgs(): array { + return $this->args; + } +} diff --git a/vendor/opis/json-schema/src/Errors/ErrorContainer.php b/vendor/opis/json-schema/src/Errors/ErrorContainer.php new file mode 100644 index 0000000..5cf10de --- /dev/null +++ b/vendor/opis/json-schema/src/Errors/ErrorContainer.php @@ -0,0 +1,148 @@ +maxErrors = $max_errors; + } + + /** + * @return int + */ + public function maxErrors(): int + { + return $this->maxErrors; + } + + /** + * @param ValidationError $error + * @return ErrorContainer + */ + public function add(ValidationError $error): self + { + $this->errors[] = $error; + return $this; + } + + /** + * @return ValidationError[] + */ + public function all(): array + { + return $this->errors; + } + + /** + * @return ValidationError|null + */ + public function first(): ?ValidationError + { + if (!$this->errors) { + return null; + } + + return reset($this->errors); + } + + /** + * @return bool + */ + public function isFull(): bool + { + return count($this->errors) >= $this->maxErrors; + } + + /** + * @return bool + */ + public function isEmpty(): bool + { + return !$this->errors; + } + + /** + * @inheritDoc + */ + public function count(): int + { + return count($this->errors); + } + + /** + * @inheritDoc + */ + public function current(): ?ValidationError + { + return current($this->errors) ?: null; + } + + /** + * @inheritDoc + */ + #[\ReturnTypeWillChange] + public function next(): ?ValidationError + { + return next($this->errors) ?: null; + } + + /** + * @inheritDoc + */ + public function key(): ?int + { + return key($this->errors); + } + + /** + * @inheritDoc + */ + public function valid(): bool + { + return key($this->errors) !== null; + } + + /** + * @inheritDoc + */ + #[\ReturnTypeWillChange] + public function rewind(): ?ValidationError + { + return reset($this->errors) ?: null; + } +} diff --git a/vendor/opis/json-schema/src/Errors/ErrorFormatter.php b/vendor/opis/json-schema/src/Errors/ErrorFormatter.php new file mode 100644 index 0000000..7db2879 --- /dev/null +++ b/vendor/opis/json-schema/src/Errors/ErrorFormatter.php @@ -0,0 +1,423 @@ +getErrors($error) as $error => $message) { + $key = $key_formatter($error); + + if ($multiple) { + if (!isset($list[$key])) { + $list[$key] = []; + } + $list[$key][] = $formatter($error, $message); + } else { + if (!isset($list[$key])) { + $list[$key] = $formatter($error, $message); + } + } + } + + return $list; + } + + /** + * @param ValidationError|null $error + * @param string $mode One of: flag, basic, detailed or verbose + * @return array + */ + public function formatOutput(?ValidationError $error, string $mode = "flag"): array + { + if ($error === null) { + return ['valid' => true]; + } + + if ($mode === 'flag') { + return ['valid' => false]; + } + + if ($mode === 'basic') { + return [ + 'valid' => false, + 'errors' => $this->formatFlat($error, [$this, 'formatOutputError']), + ]; + } + + if ($mode === 'detailed' || $mode === 'verbose') { + $isVerbose = $mode === 'verbose'; + + return $this->getNestedErrors($error, function (ValidationError $error, ?array $subErrors = null) use ($isVerbose) { + $info = $this->formatOutputError($error); + + $info['valid'] = false; + + if ($isVerbose) { + $id = $error->schema()->info(); + $id = $id->root() ?? $id->id(); + if ($id) { + $id = rtrim($id, '#'); + } + $info['absoluteKeywordLocation'] = $id . $info['keywordLocation']; + } + + if ($subErrors) { + $info['errors'] = $subErrors; + if (!$isVerbose) { + unset($info['error']); + } + } + + return $info; + } + ); + } + + return ['valid' => false]; + } + + /** + * @param ValidationError $error + * @param ?callable(ValidationError,?array):mixed $formatter + * @return mixed + */ + public function formatNested(ValidationError $error, ?callable $formatter = null) + { + if (!$formatter) { + $formatter = function (ValidationError $error, ?array $subErrors = null): array { + $ret = [ + 'message' => $this->formatErrorMessage($error), + 'keyword' => $error->keyword(), + 'path' => $this->formatErrorKey($error), + ]; + + if ($subErrors) { + $ret['errors'] = $subErrors; + } + + return $ret; + }; + } + + return $this->getNestedErrors($error, $formatter); + } + + /** + * @param ValidationError $error + * @param ?callable(ValidationError):mixed $formatter + * @return array + */ + public function formatFlat(ValidationError $error, ?callable $formatter = null): array + { + if (!$formatter) { + $formatter = [$this, 'formatErrorMessage']; + } + + $list = []; + + foreach ($this->getFlatErrors($error) as $error) { + $list[] = $formatter($error); + } + + return $list; + } + + /** + * @param ValidationError $error + * @param ?callable(ValidationError):mixed $formatter + * @param ?callable(ValidationError):string $key_formatter + * @return array + */ + public function formatKeyed( + ValidationError $error, + ?callable $formatter = null, + ?callable $key_formatter = null + ): array { + if (!$formatter) { + $formatter = [$this, 'formatErrorMessage']; + } + + if (!$key_formatter) { + $key_formatter = [$this, 'formatErrorKey']; + } + + $list = []; + + foreach ($this->getLeafErrors($error) as $error) { + $key = $key_formatter($error); + + if (!isset($list[$key])) { + $list[$key] = []; + } + + $list[$key][] = $formatter($error); + } + + return $list; + } + + /** + * @param ValidationError $error + * @param string|null $message The message to use, if null $error->message() is used + * @return string + */ + public function formatErrorMessage(ValidationError $error, ?string $message = null): string + { + $message ??= $error->message(); + $args = $this->getDefaultArgs($error) + $error->args(); + + if (!$args) { + return $message; + } + + return preg_replace_callback( + '~{([^}]+)}~imu', + static function (array $m) use ($args) { + if (!isset($args[$m[1]])) { + return $m[0]; + } + + $value = $args[$m[1]]; + + if (is_array($value)) { + return implode(', ', $value); + } + + return (string) $value; + }, + $message + ); + } + + public function formatErrorKey(ValidationError $error): string + { + return JsonPointer::pathToString($error->data()->fullPath()); + } + + protected function getDefaultArgs(ValidationError $error): array + { + $data = $error->data(); + $info = $error->schema()->info(); + + $path = $info->path(); + $path[] = $error->keyword(); + + return [ + 'data:type' => $data->type(), + 'data:value' => $data->value(), + 'data:path' => JsonPointer::pathToString($data->fullPath()), + + 'schema:id' => $info->id(), + 'schema:root' => $info->root(), + 'schema:base' => $info->base(), + 'schema:draft' => $info->draft(), + 'schema:keyword' => $error->keyword(), + 'schema:path' => JsonPointer::pathToString($path), + ]; + } + + protected function formatOutputError(ValidationError $error): array + { + $path = $error->schema()->info()->path(); + + $path[] = $error->keyword(); + + return [ + 'keywordLocation' => JsonPointer::pathToFragment($path), + 'instanceLocation' => JsonPointer::pathToFragment($error->data()->fullPath()), + 'error' => $this->formatErrorMessage($error), + ]; + } + + /** + * @param ValidationError $error + * @param callable(ValidationError,?array):mixed $formatter + * @return mixed + */ + protected function getNestedErrors(ValidationError $error, callable $formatter) + { + if ($subErrors = $error->subErrors()) { + foreach ($subErrors as &$subError) { + $subError = $this->getNestedErrors($subError, $formatter); + unset($subError); + } + } + + return $formatter($error, $subErrors); + } + + /** + * @param ValidationError $error + * @return iterable|ValidationError[] + */ + protected function getFlatErrors(ValidationError $error): iterable + { + yield $error; + + foreach ($error->subErrors() as $subError) { + yield from $this->getFlatErrors($subError); + } + } + + /** + * @param ValidationError $error + * @return iterable|ValidationError[] + */ + protected function getLeafErrors(ValidationError $error): iterable + { + if ($subErrors = $error->subErrors()) { + foreach ($subErrors as $subError) { + yield from $this->getLeafErrors($subError); + } + } else { + yield $error; + } + } + + /** + * @param ValidationError $error + * @return iterable + */ + protected function getErrors(ValidationError $error): iterable + { + $data = $error->schema()->info()->data(); + + $map = null; + $pMap = null; + + if (is_object($data)) { + switch ($error->keyword()) { + case 'required': + if (isset($data->{'$error'}->required) && is_object($data->{'$error'}->required)) { + $e = $data->{'$error'}->required; + $found = false; + foreach ($error->args()['missing'] as $prop) { + if (isset($e->{$prop})) { + yield $error => $e->{$prop}; + $found = true; + } + } + if ($found) { + return; + } + if (isset($e->{'*'})) { + yield $error => $e->{'*'}; + return; + } + unset($e, $found, $prop); + } + break; + case '$filters': + if (($args = $error->args()) && isset($args['args']['$error'])) { + yield $error => $args['args']['$error']; + return; + } + unset($args); + break; + } + + if (isset($data->{'$error'})) { + $map = $data->{'$error'}; + + if (is_string($map)) { + // We have an global error + yield $error => $map; + return; + } + + if (is_object($map)) { + if (isset($map->{$error->keyword()})) { + $pMap = $map->{'*'} ?? null; + $map = $map->{$error->keyword()}; + if (is_string($map)) { + yield $error => $map; + return; + } + } elseif (isset($map->{'*'})) { + yield $error => $map->{'*'}; + return; + } + } + } + } + + if (!is_object($map)) { + $map = null; + } + + $subErrors = $error->subErrors(); + + if (!$subErrors) { + yield $error => $pMap ?? $error->message(); + return; + } + + if (!$map) { + foreach ($subErrors as $subError) { + yield from $this->getErrors($subError); + } + return; + } + + foreach ($subErrors as $subError) { + $path = $subError->data()->path(); + if (count($path) !== 1) { + yield from $this->getErrors($subError); + } else { + $path = $path[0]; + if (isset($map->{$path})) { + yield $subError => $map->{$path}; + } elseif (isset($map->{'*'})) { + yield $subError => $map->{'*'}; + } else { + yield from $this->getErrors($subError); + } + } + } + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Errors/ValidationError.php b/vendor/opis/json-schema/src/Errors/ValidationError.php new file mode 100644 index 0000000..f7c11a4 --- /dev/null +++ b/vendor/opis/json-schema/src/Errors/ValidationError.php @@ -0,0 +1,96 @@ +keyword = $keyword; + $this->schema = $schema; + $this->data = $data; + $this->message = $message; + $this->args = $args; + $this->subErrors = $subErrors; + } + + public function keyword(): string + { + return $this->keyword; + } + + public function schema(): Schema + { + return $this->schema; + } + + public function data(): DataInfo + { + return $this->data; + } + + public function args(): array + { + return $this->args; + } + + public function message(): string + { + return $this->message; + } + + public function subErrors(): array + { + return $this->subErrors; + } + + public function __toString(): string + { + return $this->message; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/DuplicateSchemaIdException.php b/vendor/opis/json-schema/src/Exceptions/DuplicateSchemaIdException.php new file mode 100644 index 0000000..b943ec8 --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/DuplicateSchemaIdException.php @@ -0,0 +1,57 @@ +id = $id; + $this->data = $data; + } + + /** + * @return null|object + */ + public function getData(): ?object + { + return $this->data; + } + + /** + * @return Uri + */ + public function getId(): Uri + { + return $this->id; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/InvalidKeywordException.php b/vendor/opis/json-schema/src/Exceptions/InvalidKeywordException.php new file mode 100644 index 0000000..33a3409 --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/InvalidKeywordException.php @@ -0,0 +1,46 @@ +keyword = $keyword; + } + + /** + * @return string + */ + public function keyword(): string + { + return $this->keyword; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/InvalidPragmaException.php b/vendor/opis/json-schema/src/Exceptions/InvalidPragmaException.php new file mode 100644 index 0000000..d3ff204 --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/InvalidPragmaException.php @@ -0,0 +1,46 @@ +pragma = $pragma; + } + + /** + * @return string + */ + public function pragma(): string + { + return $this->pragma; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/ParseException.php b/vendor/opis/json-schema/src/Exceptions/ParseException.php new file mode 100644 index 0000000..23e84f9 --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/ParseException.php @@ -0,0 +1,45 @@ +info = $info; + } + + /** + * @return SchemaInfo|null + */ + public function schemaInfo(): ?SchemaInfo + { + return $this->info; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/SchemaException.php b/vendor/opis/json-schema/src/Exceptions/SchemaException.php new file mode 100644 index 0000000..feedbcd --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/SchemaException.php @@ -0,0 +1,25 @@ +encoding = $encoding; + } + + /** + * @return string + */ + public function getContentEncoding(): string + { + return $this->encoding; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/UnresolvedContentMediaTypeException.php b/vendor/opis/json-schema/src/Exceptions/UnresolvedContentMediaTypeException.php new file mode 100644 index 0000000..ef83d98 --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/UnresolvedContentMediaTypeException.php @@ -0,0 +1,44 @@ +media = $media; + } + + /** + * @return string + */ + public function getContentMediaType(): string + { + return $this->media; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/UnresolvedException.php b/vendor/opis/json-schema/src/Exceptions/UnresolvedException.php new file mode 100644 index 0000000..fb876cf --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/UnresolvedException.php @@ -0,0 +1,57 @@ +schema = $schema; + $this->context = $context; + } + + /** + * @return Schema + */ + public function getSchema(): Schema + { + return $this->schema; + } + + /** + * @return ValidationContext + */ + public function getContext(): ValidationContext + { + return $this->context; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/UnresolvedFilterException.php b/vendor/opis/json-schema/src/Exceptions/UnresolvedFilterException.php new file mode 100644 index 0000000..180693e --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/UnresolvedFilterException.php @@ -0,0 +1,57 @@ +filter = $filter; + $this->type = $type; + } + + /** + * @return string + */ + public function getFilter(): string + { + return $this->filter; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Exceptions/UnresolvedReferenceException.php b/vendor/opis/json-schema/src/Exceptions/UnresolvedReferenceException.php new file mode 100644 index 0000000..5c48bed --- /dev/null +++ b/vendor/opis/json-schema/src/Exceptions/UnresolvedReferenceException.php @@ -0,0 +1,45 @@ +ref = $ref; + } + + /** + * @return string + */ + public function getRef(): string + { + return $this->ref; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Filter.php b/vendor/opis/json-schema/src/Filter.php new file mode 100644 index 0000000..1e1b002 --- /dev/null +++ b/vendor/opis/json-schema/src/Filter.php @@ -0,0 +1,29 @@ +currentData(); + if (!is_string($ref)) { + return false; + } + + $ref = JsonPointer::parse($ref); + if ($ref === null) { + return false; + } + + return $ref->data($context->rootData(), $context->currentDataPath(), $this) !== $this; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Filters/DateTimeFilters.php b/vendor/opis/json-schema/src/Filters/DateTimeFilters.php new file mode 100644 index 0000000..fe599fc --- /dev/null +++ b/vendor/opis/json-schema/src/Filters/DateTimeFilters.php @@ -0,0 +1,100 @@ += self::CreateDate($min, $tz, false); + } + + public static function MaxDate(string $date, array $args): bool + { + $max = $args['value']; + $tz = $args['timezone'] ?? null; + + return self::CreateDate($date, $tz, false) <= self::CreateDate($max, $tz, false); + } + + public static function NotDate(string $date, array $args): bool + { + $not = $args['value']; + $tz = $args['timezone'] ?? null; + + if (!is_array($not)) { + $not = [$not]; + } + + $date = self::CreateDate($date, $tz, false); + + foreach ($not as $d) { + if ($date == self::CreateDate($d, $tz, false)) { + return false; + } + } + + return true; + } + + public static function MinDateTime(string $date, array $args): bool + { + $min = $args['value']; + $tz = $args['timezone'] ?? null; + + return self::CreateDate($date, $tz) >= self::CreateDate($min, $tz); + } + + public static function MaxDateTime(string $date, array $args): bool + { + $max = $args['value']; + $tz = $args['timezone'] ?? null; + + return self::CreateDate($date, $tz) <= self::CreateDate($max, $tz); + } + + public static function MinTime(string $time, array $args): bool + { + $min = $args['value']; + $prefix = '1970-01-01 '; + + return self::CreateDate($prefix . $time) >= self::CreateDate($prefix . $min); + } + + public static function MaxTime(string $time, array $args): bool + { + $max = $args['value']; + $prefix = '1970-01-01 '; + + return self::CreateDate($prefix . $time) <= self::CreateDate($prefix . $max); + } + + private static function CreateDate(string $value, ?string $timezone = null, bool $time = true): DateTime + { + $date = new DateTime($value, $timezone); + if (!$time) { + return $date->setTime(0, 0, 0, 0); + } + return $date; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Filters/FilterExistsFilter.php b/vendor/opis/json-schema/src/Filters/FilterExistsFilter.php new file mode 100644 index 0000000..3b92ade --- /dev/null +++ b/vendor/opis/json-schema/src/Filters/FilterExistsFilter.php @@ -0,0 +1,54 @@ +currentData(); + if (!is_string($filter)) { + return false; + } + + $type = null; + if (isset($args['type'])) { + if (!is_string($args['type'])) { + return false; + } + $type = $args['type']; + } + + $resolver = $context->loader()->parser()->getFilterResolver(); + + if (!$resolver) { + return false; + } + + if ($type === null) { + return (bool)$resolver->resolveAll($filter); + } + + return (bool)$resolver->resolve($filter, $type); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Filters/FormatExistsFilter.php b/vendor/opis/json-schema/src/Filters/FormatExistsFilter.php new file mode 100644 index 0000000..dacd482 --- /dev/null +++ b/vendor/opis/json-schema/src/Filters/FormatExistsFilter.php @@ -0,0 +1,54 @@ +currentData(); + if (!is_string($format)) { + return false; + } + + $type = null; + if (isset($args['type'])) { + if (!is_string($args['type'])) { + return false; + } + $type = $args['type']; + } + + $resolver = $context->loader()->parser()->getFormatResolver(); + + if (!$resolver) { + return false; + } + + if ($type === null) { + return (bool)$resolver->resolveAll($format); + } + + return (bool)$resolver->resolve($format, $type); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Filters/GlobalVarExistsFilter.php b/vendor/opis/json-schema/src/Filters/GlobalVarExistsFilter.php new file mode 100644 index 0000000..44aa396 --- /dev/null +++ b/vendor/opis/json-schema/src/Filters/GlobalVarExistsFilter.php @@ -0,0 +1,47 @@ +currentData(); + + if (!is_string($var)) { + return false; + } + + $globals = $context->globals(); + + if (!array_key_exists($var, $globals)) { + return false; + } + + if (array_key_exists('value', $args)) { + return $globals[$var] == $args['value']; + } + + return true; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Filters/SchemaExistsFilter.php b/vendor/opis/json-schema/src/Filters/SchemaExistsFilter.php new file mode 100644 index 0000000..4570bcb --- /dev/null +++ b/vendor/opis/json-schema/src/Filters/SchemaExistsFilter.php @@ -0,0 +1,84 @@ +currentData(); + if (!is_string($ref)) { + return false; + } + + if (UriTemplate::isTemplate($ref)) { + if (isset($args['vars']) && is_object($args['vars'])) { + $vars = new VariablesContainer($args['vars'], false); + $vars = $vars->resolve($context->rootData(), $context->currentDataPath()); + if (!is_array($vars)) { + $vars = (array)$vars; + } + $vars += $context->globals(); + } else { + $vars = $context->globals(); + } + + $ref = (new UriTemplate($ref))->resolve($vars); + + unset($vars); + } + + unset($args); + + return $this->refExists($ref, $context, $schema); + } + + /** + * @param string $ref + * @param ValidationContext $context + * @param Schema $schema + * @return bool + */ + protected function refExists(string $ref, ValidationContext $context, Schema $schema): bool + { + if ($ref === '') { + return false; + } + + if ($ref === '#') { + return true; + } + + $info = $schema->info(); + + $id = Uri::merge($ref, $info->idBaseRoot(), true); + + if ($id === null) { + return false; + } + + return $context->loader()->loadSchemaById($id) !== null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Filters/SlotExistsFilter.php b/vendor/opis/json-schema/src/Filters/SlotExistsFilter.php new file mode 100644 index 0000000..b703bab --- /dev/null +++ b/vendor/opis/json-schema/src/Filters/SlotExistsFilter.php @@ -0,0 +1,36 @@ +currentData(); + if (!is_string($slot)) { + return false; + } + + return $context->slot($slot) !== null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Format.php b/vendor/opis/json-schema/src/Format.php new file mode 100644 index 0000000..577a534 --- /dev/null +++ b/vendor/opis/json-schema/src/Format.php @@ -0,0 +1,27 @@ +.+)@(?.+)$/u', $value, $m)) { + return false; + } + + $m['name'] = $idn($m['name']); + if ($m['name'] === null) { + return false; + } + + $m['domain'] = $idn($m['domain']); + if ($m['domain'] === null) { + return false; + } + + $value = $m['name'] . '@' . $m['domain']; + } + + return filter_var($value, FILTER_VALIDATE_EMAIL) !== false; + } + + /** + * @return callable|null + */ + public static function idn(): ?callable + { + if (static::$idn === false) { + if (function_exists('idn_to_ascii')) { + static::$idn = static function (string $value): ?string { + /** @noinspection PhpComposerExtensionStubsInspection */ + $value = idn_to_ascii($value, 0, INTL_IDNA_VARIANT_UTS46); + + return is_string($value) ? $value : null; + }; + } else { + static::$idn = null; + } + } + + return static::$idn; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Formats/MiscFormats.php b/vendor/opis/json-schema/src/Formats/MiscFormats.php new file mode 100644 index 0000000..a7e2af5 --- /dev/null +++ b/vendor/opis/json-schema/src/Formats/MiscFormats.php @@ -0,0 +1,59 @@ +isAbsolute(); + } + + /** + * @param string $value + * @return bool + */ + public static function uriReference(string $value): bool + { + if ($value === '') { + return true; + } + + return Uri::parse($value) !== null; + } + + /** + * @param string $value + * @return bool + */ + public static function uriTemplate(string $value): bool + { + if ($value === '') { + return true; + } + + if (UriTemplate::isTemplate($value)) { + return true; + } + + return Uri::parse($value) !== null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Helper.php b/vendor/opis/json-schema/src/Helper.php new file mode 100644 index 0000000..6818804 --- /dev/null +++ b/vendor/opis/json-schema/src/Helper.php @@ -0,0 +1,351 @@ + 'number']; + + /** @var string[] */ + protected const PHP_TYPE_MAP = [ + 'NULL' => 'null', + 'integer' => 'integer', + 'double' => 'number', + 'boolean' => 'boolean', + 'array' => 'array', + 'object' => 'object', + 'string' => 'string', + ]; + + /** + * @param string $type + * @return bool + */ + public static function isValidJsonType(string $type): bool + { + if (isset(self::JSON_SUBTYPES[$type])) { + return true; + } + + return in_array($type, self::JSON_TYPES, true); + } + + /** + * @param string $type + * @return null|string + */ + public static function getJsonSuperType(string $type): ?string + { + return self::JSON_SUBTYPES[$type] ?? null; + } + + /** + * @param mixed $value + * @param bool $use_subtypes + * @return null|string + */ + public static function getJsonType($value, bool $use_subtypes = true): ?string + { + $type = self::PHP_TYPE_MAP[gettype($value)] ?? null; + if ($type === null) { + return null; + } elseif ($type === 'array') { + return self::isIndexedArray($value) ? 'array' : null; + } + + if ($use_subtypes) { + if ($type === 'number' && self::isMultipleOf($value, 1)) { + return 'integer'; + } + } elseif ($type === 'integer') { + return 'number'; + } + + return $type; + } + + /** + * @param string $type + * @param string|string[] $allowed + * @return bool + */ + public static function jsonTypeMatches(string $type, $allowed): bool + { + if (!$allowed) { + return false; + } + + if (is_string($allowed)) { + if ($type === $allowed) { + return true; + } + + return $allowed === self::getJsonSuperType($type); + } + + if (is_array($allowed)) { + if (in_array($type, $allowed, true)) { + return true; + } + + if ($type = self::getJsonSuperType($type)) { + return in_array($type, $allowed, true); + } + } + + return false; + } + + /** + * @param mixed $value + * @param string|string[] $type + * @return bool + */ + public static function valueIsOfJsonType($value, $type): bool + { + $t = self::getJsonType($value); + if ($t === null) { + return false; + } + + return self::jsonTypeMatches($t, $type); + } + + /** + * @param array $array + * @return bool + */ + public static function isIndexedArray(array $array): bool + { + for ($i = 0, $max = count($array); $i < $max; $i++) { + if (!array_key_exists($i, $array)) { + return false; + } + } + + return true; + } + + /** + * Converts assoc-arrays to objects (recursive) + * @param scalar|object|array|null $schema + * @return scalar|object|array|null + */ + public static function convertAssocArrayToObject($schema) + { + if (is_null($schema) || is_scalar($schema)) { + return $schema; + } + + $keepArray = is_array($schema) && self::isIndexedArray($schema); + + $data = []; + + foreach ($schema as $key => $value) { + $data[$key] = is_array($value) || is_object($value) ? self::convertAssocArrayToObject($value) : $value; + } + + return $keepArray ? $data : (object) $data; + } + + /** + * @param mixed $a + * @param mixed $b + * @return bool + */ + public static function equals($a, $b): bool + { + if ($a === $b) { + return true; + } + + $type = self::getJsonType($a, false); + if ($type === null || $type !== self::getJsonType($b, false)) { + return false; + } + + if ($type === 'number') { + return $a == $b; + } + + if ($type === "array") { + $count = count($a); + if ($count !== count($b)) { + return false; + } + + for ($i = 0; $i < $count; $i++) { + if (!array_key_exists($i, $a) || !array_key_exists($i, $b)) { + return false; + } + if (!self::equals($a[$i], $b[$i])) { + return false; + } + } + + return true; + } + + if ($type === "object") { + $a = get_object_vars($a); + if ($a === null) { + return false; + } + + $b = get_object_vars($b); + if ($b === null) { + return false; + } + + if (count($a) !== count($b)) { + return false; + } + + foreach ($a as $prop => $value) { + if (!array_key_exists($prop, $b)) { + return false; + } + if (!self::equals($value, $b[$prop])) { + return false; + } + } + + return true; + } + + return false; + } + + /** + * @param $number + * @param $divisor + * @param int $scale + * @return bool + */ + public static function isMultipleOf($number, $divisor, int $scale = 14): bool + { + static $bcMath = null; + if ($bcMath === null) { + $bcMath = extension_loaded('bcmath'); + } + if ($divisor == 0) { + return $number == 0; + } + + if ($bcMath) { + $number = number_format($number, $scale, '.', ''); + $divisor = number_format($divisor, $scale, '.', ''); + + /** @noinspection PhpComposerExtensionStubsInspection */ + $x = bcdiv($number, $divisor, 0); + /** @noinspection PhpComposerExtensionStubsInspection */ + $x = bcmul($divisor, $x, $scale); + /** @noinspection PhpComposerExtensionStubsInspection */ + $x = bcsub($number, $x, $scale); + + /** @noinspection PhpComposerExtensionStubsInspection */ + return 0 === bccomp($x, 0, $scale); + } + + $div = $number / $divisor; + + return $div == (int)$div; + } + + /** + * @param $value + * @return mixed + */ + public static function cloneValue($value) + { + if ($value === null || is_scalar($value)) { + return $value; + } + + if (is_array($value)) { + return array_map(self::class . '::cloneValue', $value); + } + + if (is_object($value)) { + return (object)array_map(self::class . '::cloneValue', get_object_vars($value)); + } + + return null; + } + + /** + * @param string $pattern + * @return bool + */ + public static function isValidPattern(string $pattern): bool + { + if (strpos($pattern, '\Z') !== false) { + return false; + } + + return @preg_match("\x07{$pattern}\x07u", '') !== false; + } + + /** + * @param string $pattern + * @return string + */ + public static function patternToRegex(string $pattern): string + { + return "\x07{$pattern}\x07uD"; + } + + /** + * @param mixed $data + * @return mixed + */ + public static function toJSON($data) + { + if ($data === null || is_scalar($data)) { + return $data; + } + + $map = []; + + $isArray = true; + $index = 0; + foreach ($data as $key => $value) { + $map[$key] = self::toJSON($value); + if ($isArray) { + if ($index !== $key) { + $isArray = false; + } else { + $index++; + } + } + } + + if ($isArray) { + if (!$map && is_object($data)) { + return (object) $map; + } + return $map; + } + + return (object) $map; + } +} diff --git a/vendor/opis/json-schema/src/Info/DataInfo.php b/vendor/opis/json-schema/src/Info/DataInfo.php new file mode 100644 index 0000000..57dc8a7 --- /dev/null +++ b/vendor/opis/json-schema/src/Info/DataInfo.php @@ -0,0 +1,114 @@ +value = $value; + $this->type = $type; + $this->root = $root; + $this->path = $path; + $this->parent = $parent; + } + + public function value() + { + return $this->value; + } + + public function type(): ?string + { + return $this->type; + } + + public function root() + { + return $this->root; + } + + /** + * @return int[]|string[] + */ + public function path(): array + { + return $this->path; + } + + public function parent(): ?DataInfo + { + return $this->parent; + } + + /** + * @return int[]|string[] + */ + public function fullPath(): array + { + if ($this->parent === null) { + return $this->path; + } + + if ($this->fullPath === null) { + $this->fullPath = array_merge($this->parent->fullPath(), $this->path); + } + + return $this->fullPath; + } + + /** + * @param ValidationContext $context + * @return static + */ + public static function fromContext(ValidationContext $context): self + { + if ($parent = $context->parent()) { + $parent = self::fromContext($parent); + } + + return new self($context->currentData(), $context->currentDataType(), $context->rootData(), + $context->currentDataPath(), $parent); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Info/SchemaInfo.php b/vendor/opis/json-schema/src/Info/SchemaInfo.php new file mode 100644 index 0000000..77b2d05 --- /dev/null +++ b/vendor/opis/json-schema/src/Info/SchemaInfo.php @@ -0,0 +1,117 @@ +data = $data; + $this->id = $id; + $this->root = $root; + $this->base = $base; + $this->path = $path; + $this->draft = $draft; + } + + public function id(): ?Uri + { + return $this->id; + } + + public function root(): ?Uri + { + return $this->root; + } + + public function base(): ?Uri + { + return $this->base; + } + + public function draft(): ?string + { + return $this->draft; + } + + public function data() + { + return $this->data; + } + + public function path(): array + { + return $this->path; + } + + /** + * Returns first non-null property: id, base or root + * @return Uri|null + */ + public function idBaseRoot(): ?Uri + { + return $this->id ?? $this->base ?? $this->root; + } + + public function isBoolean(): bool + { + return is_bool($this->data); + } + + public function isObject(): bool + { + return is_object($this->data); + } + + public function isDocumentRoot(): bool + { + return $this->id && !$this->root && !$this->base; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/JsonPointer.php b/vendor/opis/json-schema/src/JsonPointer.php new file mode 100644 index 0000000..1c78e23 --- /dev/null +++ b/vendor/opis/json-schema/src/JsonPointer.php @@ -0,0 +1,410 @@ +0|[1-9][0-9]*)(?(?:\+|-)(?:0|[1-9][0-9]*))?)?(?(?:/[^/#]*)*)(?#)?$~'; + + /** @var string */ + protected const UNESCAPED = '/~([^01]|$)/'; + + protected int $level = -1; + + protected int $shift = 0; + + protected bool $fragment = false; + + /** @var string[]|int[] */ + protected array $path; + + protected ?string $str = null; + + final protected function __construct(array $path, int $level = -1, int $shift = 0, bool $fragment = false) + { + $this->path = $path; + $this->level = $level < 0 ? -1 : $level; + $this->shift = $shift; + $this->fragment = $level >= 0 && $fragment; + } + + public function isRelative(): bool + { + return $this->level >= 0; + } + + public function isAbsolute(): bool + { + return $this->level < 0; + } + + public function level(): int + { + return $this->level; + } + + public function shift(): int + { + return $this->shift; + } + + /** + * @return string[] + */ + public function path(): array + { + return $this->path; + } + + /** + * @return bool + */ + public function hasFragment(): bool + { + return $this->fragment; + } + + /** + * @return string + */ + public function __toString(): string + { + if ($this->str === null) { + if ($this->level >= 0) { + $this->str = (string)$this->level; + + if ($this->shift !== 0) { + if ($this->shift > 0) { + $this->str .= '+'; + } + $this->str .= $this->shift; + } + + if ($this->path) { + $this->str .= '/'; + $this->str .= implode('/', self::encodePath($this->path)); + } + + if ($this->fragment) { + $this->str .= '#'; + } + } else { + $this->str = '/'; + $this->str .= implode('/', self::encodePath($this->path)); + } + } + + return $this->str; + } + + /** + * @param $data + * @param array|null $path + * @param null $default + * @return mixed + */ + public function data($data, ?array $path = null, $default = null) + { + if ($this->level < 0) { + return self::getData($data, $this->path, false, $default); + } + + if ($path !== null) { + $path = $this->absolutePath($path); + } + + if ($path === null) { + return $default; + } + + return self::getData($data, $path, $this->fragment, $default); + } + + /** + * @param array $path + * @return array|null + */ + public function absolutePath(array $path = []): ?array + { + if ($this->level < 0) { + // Absolute pointer + return $this->path; + } + + if ($this->level === 0) { + if ($this->shift && !$this->handleShift($path)) { + return null; + } + return $this->path ? array_merge($path, $this->path) : $path; + } + + $count = count($path); + if ($count === $this->level) { + if ($this->shift) { + return null; + } + return $this->path; + } + + if ($count > $this->level) { + $count -= $this->level; + + /** @var array $path */ + $path = array_slice($path, 0, $count); + + if ($this->shift && !$this->handleShift($path, $count)) { + return null; + } + + return $this->path ? array_merge($path, $this->path) : $path; + } + + return null; + } + + protected function handleShift(array &$path, ?int $count = null): bool + { + if (!$path) { + return false; + } + + $count ??= count($path); + + $last = $path[$count - 1]; + + if (is_string($last) && preg_match('/^[1-9]\d*$/', $last)) { + $last = (int) $last; + } + + if (!is_int($last)) { + return false; + } + + $path[$count - 1] = $last + $this->shift; + + return true; + } + + public static function parse(string $pointer, bool $decode = true): ?self + { + if ($pointer === '' || !preg_match(self::PATTERN, $pointer, $m)) { + // Not a pointer + return null; + } + + $pointer = $m['pointer'] ?? null; + + // Check if the pointer is escaped + if ($decode && $pointer && preg_match(self::UNESCAPED, $pointer)) { + // Invalid pointer + return null; + } + + $level = isset($m['level']) && $m['level'] !== '' + ? (int)$m['level'] + : -1; + + $shift = 0; + if ($level >= 0 && isset($m['shift']) && $m['shift'] !== '') { + $shift = (int) $m['shift']; + } + + $fragment = isset($m['fragment']) && $m['fragment'] === '#'; + unset($m); + + if ($fragment && $level < 0) { + return null; + } + + if ($pointer === '') { + $pointer = null; + } elseif ($pointer !== null) { + // Remove leading slash + $pointer = substr($pointer, 1); + + if ($pointer !== '') { + $pointer = self::decodePath(explode('/', $pointer)); + } else { + $pointer = null; + } + } + + return new self($pointer ?? [], $level, $shift, $fragment); + } + + /** + * @param $data + * @param array|null $path + * @param bool $fragment + * @param null $default + * @return mixed + */ + public static function getData($data, ?array $path = null, bool $fragment = false, $default = null) + { + if ($path === null) { + return $default; + } + + if (!$path) { + return $fragment ? $default : $data; + } + + if ($fragment) { + return end($path); + } + + foreach ($path as $key) { + if (is_array($data)) { + if (!array_key_exists($key, $data)) { + return $default; + } + $data = $data[$key]; + } elseif (is_object($data)) { + if (!property_exists($data, $key)) { + return $default; + } + $data = $data->{$key}; + } else { + return $default; + } + } + + return $data; + } + + /** + * @param string|string[] $path + * @return string|string[] + */ + public static function encodePath($path) + { + $path = str_replace('~', '~0', $path); + $path = str_replace('/', '~1', $path); + + if (is_array($path)) { + return array_map('rawurlencode', $path); + } + + return rawurlencode($path); + } + + /** + * @param string|string[] $path + * @return string|string[] + */ + public static function decodePath($path) + { + if (is_array($path)) { + $path = array_map('rawurldecode', $path); + } else { + $path = rawurldecode($path); + } + + $path = str_replace('~1', '/', $path); + $path = str_replace('~0', '~', $path); + + return $path; + } + + /** + * @param array $path + * @return string + */ + public static function pathToString(array $path): string + { + if (!$path) { + return '/'; + } + + return '/' . implode('/', self::encodePath($path)); + } + + /** + * @param array $path + * @return string + */ + public static function pathToFragment(array $path): string + { + if (!$path) { + return '#'; + } + + return '#/' . implode('/', self::encodePath($path)); + } + + /** + * @param string $pointer + * @return bool + */ + public static function isAbsolutePointer(string $pointer): bool + { + if ($pointer === '/') { + return true; + } + + if (!preg_match(self::PATTERN, $pointer, $m)) { + return false; + } + + if (isset($m['fragment']) || isset($m['level']) && $m['level'] !== '') { + return false; + } + + if (!isset($m['pointer']) || $m['pointer'] === '') { + return true; + } + + return !preg_match(self::UNESCAPED, $m['pointer']); + } + + /** + * @param string $pointer + * @return bool + */ + public static function isRelativePointer(string $pointer): bool + { + if ($pointer === '') { + return false; + } + + if (!preg_match(self::PATTERN, $pointer, $m)) { + return false; + } + + if (!isset($m['level']) || $m['level'] === '' || (int)$m['level'] < 0) { + return false; + } + + if (!isset($m['pointer']) || $m['pointer'] === '') { + return true; + } + + return !preg_match(self::UNESCAPED, $m['pointer']); + } + + public static function createAbsolute(array $path): self + { + return new self($path, -1, 0, false); + } + + public static function createRelative(int $level, array $path = [], int $shift = 0, bool $fragment = false): self + { + return new self($path, $level, $shift, $fragment); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keyword.php b/vendor/opis/json-schema/src/Keyword.php new file mode 100644 index 0000000..d10c903 --- /dev/null +++ b/vendor/opis/json-schema/src/Keyword.php @@ -0,0 +1,30 @@ +next; + } + + /** + * @inheritDoc + */ + public function setNext(?KeywordValidator $next): KeywordValidator + { + $this->next = $next; + + return $this; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/KeywordValidators/CallbackKeywordValidator.php b/vendor/opis/json-schema/src/KeywordValidators/CallbackKeywordValidator.php new file mode 100644 index 0000000..2cb7f59 --- /dev/null +++ b/vendor/opis/json-schema/src/KeywordValidators/CallbackKeywordValidator.php @@ -0,0 +1,59 @@ +callback = $callback; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context): ?ValidationError + { + return ($this->callback)($context); + } + + /** + * @inheritDoc + */ + public function next(): ?KeywordValidator + { + return null; + } + + /** + * @inheritDoc + */ + public function setNext(?KeywordValidator $next): KeywordValidator + { + return $this; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/KeywordValidators/PragmaKeywordValidator.php b/vendor/opis/json-schema/src/KeywordValidators/PragmaKeywordValidator.php new file mode 100644 index 0000000..7913b06 --- /dev/null +++ b/vendor/opis/json-schema/src/KeywordValidators/PragmaKeywordValidator.php @@ -0,0 +1,63 @@ +pragmas = $pragmas; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context): ?ValidationError + { + if (!$this->next) { + return null; + } + + if (!$this->pragmas) { + return $this->next->validate($context); + } + + $data = []; + + foreach ($this->pragmas as $key => $handler) { + $data[$key] = $handler->enter($context); + } + + $error = $this->next->validate($context); + + foreach (array_reverse($this->pragmas, true) as $key => $handler) { + $handler->leave($context, $data[$key] ?? null); + } + + return $error; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/AbstractRefKeyword.php b/vendor/opis/json-schema/src/Keywords/AbstractRefKeyword.php new file mode 100644 index 0000000..4c8e7be --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/AbstractRefKeyword.php @@ -0,0 +1,129 @@ +mapper = $mapper; + $this->globals = $globals; + $this->slots = $slots; + $this->keyword = $keyword; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($error = $this->doValidate($context, $schema)) { + $uri = $this->lastRefUri; + $this->lastRefUri = null; + + return $this->error($schema, $context, $this->keyword, 'The data must match {keyword}', [ + 'keyword' => $this->keyword, + 'uri' => (string) $uri, + ], $error); + } + + $this->lastRefUri = null; + + return null; + } + + + abstract protected function doValidate(ValidationContext $context, Schema $schema): ?ValidationError; + + protected function setLastRefUri(?Uri $uri): void + { + $this->lastRefUri = $uri; + } + + protected function setLastRefSchema(Schema $schema): void + { + $info = $schema->info(); + + if ($info->id()) { + $this->lastRefUri = $info->id(); + } else { + $this->lastRefUri = Uri::merge(JsonPointer::pathToFragment($info->path()), $info->idBaseRoot()); + } + } + + /** + * @param ValidationContext $context + * @param Schema $schema + * @return ValidationContext + */ + protected function createContext(ValidationContext $context, Schema $schema): ValidationContext + { + return $context->create($schema, $this->mapper, $this->globals, $this->slots); + } + + /** + * @param SchemaLoader $repo + * @param JsonPointer $pointer + * @param Uri $base + * @param array|null $path + * @return null|Schema + */ + protected function resolvePointer(SchemaLoader $repo, JsonPointer $pointer, + Uri $base, ?array $path = null): ?Schema + { + if ($pointer->isAbsolute()) { + $path = (string)$pointer; + } else { + if ($pointer->hasFragment()) { + return null; + } + + $path = $path ? $pointer->absolutePath($path) : $pointer->path(); + if ($path === null) { + return null; + } + + $path = JsonPointer::pathToString($path); + } + + return $repo->loadSchemaById(Uri::merge('#' . $path, $base)); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/AdditionalItemsKeyword.php b/vendor/opis/json-schema/src/Keywords/AdditionalItemsKeyword.php new file mode 100644 index 0000000..ae0910a --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/AdditionalItemsKeyword.php @@ -0,0 +1,97 @@ +value = $value; + $this->index = $startIndex; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->value === true) { + $context->markAllAsEvaluatedItems(); + return null; + } + + $data = $context->currentData(); + $count = count($data); + + if ($this->index >= $count) { + return null; + } + + if ($this->value === false) { + return $this->error($schema, $context, 'additionalItems', 'Array should not have additional items', [ + 'index' => $this->index, + ]); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + $object = $this->createArrayObject($context); + + $error = $this->validateIterableData($schema, $this->value, $context, $this->indexes($this->index, $count), + 'additionalItems', 'All additional array items must match schema', [], $object); + + if ($object && $object->count()) { + $context->addEvaluatedItems($object->getArrayCopy()); + } + + return $error; + } + + /** + * @param int $start + * @param int $max + * @return iterable|int[] + */ + protected function indexes(int $start, int $max): iterable + { + for ($i = $start; $i < $max; $i++) { + yield $i; + } + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/AdditionalPropertiesKeyword.php b/vendor/opis/json-schema/src/Keywords/AdditionalPropertiesKeyword.php new file mode 100644 index 0000000..b3ac59f --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/AdditionalPropertiesKeyword.php @@ -0,0 +1,83 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->value === true) { + $context->markAllAsEvaluatedProperties(); + return null; + } + + $props = $context->getUncheckedProperties(); + + if (!$props) { + return null; + } + + if ($this->value === false) { + return $this->error($schema, $context, + 'additionalProperties', 'Additional object properties are not allowed: {properties}', [ + 'properties' => $props + ]); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + $object = $this->createArrayObject($context); + + $error = $this->validateIterableData($schema, $this->value, $context, $props, + 'additionalProperties', 'All additional object properties must match schema: {properties}', [ + 'properties' => $props + ], $object); + + if ($object && $object->count()) { + $context->addEvaluatedProperties($object->getArrayCopy()); + } + + return $error; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/AllOfKeyword.php b/vendor/opis/json-schema/src/Keywords/AllOfKeyword.php new file mode 100644 index 0000000..cbc9c61 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/AllOfKeyword.php @@ -0,0 +1,78 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $object = $this->createArrayObject($context); + + foreach ($this->value as $index => $value) { + if ($value === true) { + continue; + } + + if ($value === false) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'allOf', 'The data should match all schemas', [ + 'index' => $index, + ]); + } + + if (is_object($value) && !($value instanceof Schema)) { + $value = $this->value[$index] = $context->loader()->loadObjectSchema($value); + } + + if ($error = $context->validateSchemaWithoutEvaluated($value, null, false, $object)) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'allOf', 'The data should match all schemas', [ + 'index' => $index, + ], $error); + } + } + + $this->addEvaluatedFromArrayObject($object, $context); + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/AnyOfKeyword.php b/vendor/opis/json-schema/src/Keywords/AnyOfKeyword.php new file mode 100644 index 0000000..1a7f325 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/AnyOfKeyword.php @@ -0,0 +1,94 @@ +value = $value; + $this->alwaysValid = $alwaysValid; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $object = $this->createArrayObject($context); + if ($this->alwaysValid && !$object) { + return null; + } + + $errors = []; + $ok = false; + + foreach ($this->value as $index => $value) { + if ($value === true) { + $ok = true; + if ($object) { + continue; + } + return null; + } + + if ($value === false) { + continue; + } + + if (is_object($value) && !($value instanceof Schema)) { + $value = $this->value[$index] = $context->loader()->loadObjectSchema($value); + } + + if ($error = $context->validateSchemaWithoutEvaluated($value, null, false, $object)) { + $errors[] = $error; + continue; + } + + if (!$object) { + return null; + } + $ok = true; + } + + $this->addEvaluatedFromArrayObject($object, $context); + + if ($ok) { + return null; + } + + return $this->error($schema, $context, 'anyOf', 'The data should match at least one schema', [], $errors); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ConstDataKeyword.php b/vendor/opis/json-schema/src/Keywords/ConstDataKeyword.php new file mode 100644 index 0000000..4f5af4e --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ConstDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(null); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $value = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + if ($value === $this) { + return $this->error($schema, $context, 'const', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->const = $value; + $ret = parent::validate($context, $schema); + $this->const = null; + + return $ret; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ConstKeyword.php b/vendor/opis/json-schema/src/Keywords/ConstKeyword.php new file mode 100644 index 0000000..1bdb68d --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ConstKeyword.php @@ -0,0 +1,51 @@ +const = $const; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if (Helper::equals($this->const, $context->currentData())) { + return null; + } + + return $this->error($schema, $context, 'const', 'The data must must match the const value', [ + 'const' => $this->const + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ContainsKeyword.php b/vendor/opis/json-schema/src/Keywords/ContainsKeyword.php new file mode 100644 index 0000000..8d0ee95 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ContainsKeyword.php @@ -0,0 +1,143 @@ +value = $value; + $this->min = $min; + $this->max = $max; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $data = $context->currentData(); + $count = count($data); + + $context->markAllAsEvaluatedItems(); + + if ($this->min > $count) { + return $this->error($schema, $context, 'minContains', 'Array must have at least {min} items', [ + 'min' => $this->min, + 'count' => $count, + ]); + } + + $isMaxNull = $this->max === null; + + if ($this->value === true) { + if ($count) { + if (!$isMaxNull && $count > $this->max) { + return $this->error($schema, $context, 'maxContains', 'Array must have at most {max} items', [ + 'max' => $this->max, + 'count' => $count, + ]); + } + return null; + } + + return $this->error($schema, $context, 'contains', 'Array must not be empty'); + } + + if ($this->value === false) { + return $this->error($schema, $context, 'contains', 'Any array is invalid'); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + $errors = []; + $valid = 0; + + $isMinNull = $this->min === null; + + if ($isMaxNull && $isMinNull) { + foreach ($data as $key => $item) { + $context->pushDataPath($key); + $error = $this->value->validate($context); + $context->popDataPath(); + if ($error) { + $errors[] = $error; + } else { + return null; + } + } + + return $this->error($schema, $context, 'contains', 'At least one array item must match schema', [], + $errors); + } + + foreach ($data as $key => $item) { + $context->pushDataPath($key); + $error = $this->value->validate($context); + $context->popDataPath(); + + if ($error) { + $errors[] = $error; + } else { + $valid++; + } + } + + if (!$isMinNull && $valid < $this->min) { + return $this->error($schema, $context, 'minContains', 'At least {min} array items must match schema', [ + 'min' => $this->min, + 'count' => $valid, + ]); + } + + if (!$isMaxNull && $valid > $this->max) { + return $this->error($schema, $context, 'maxContains', 'At most {max} array items must match schema', [ + 'max' => $this->max, + 'count' => $valid, + ]); + } + + if ($valid) { + return null; + } + + return $this->error($schema, $context, 'contains', 'At least one array item must match schema', [], + $errors); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ContentEncodingKeyword.php b/vendor/opis/json-schema/src/Keywords/ContentEncodingKeyword.php new file mode 100644 index 0000000..54ff41a --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ContentEncodingKeyword.php @@ -0,0 +1,77 @@ +name = $name; + $this->resolver = $resolver; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if (!$this->resolver) { + return null; + } + + if ($this->encoding === false) { + $this->encoding = $this->resolver->resolve($this->name); + } + + if ($this->encoding === null) { + throw new UnresolvedContentEncodingException($this->name, $schema, $context); + } + + $result = $this->encoding instanceof ContentEncoding + ? $this->encoding->decode($context->currentData(), $this->name) + : ($this->encoding)($context->currentData(), $this->name); + + if ($result === null) { + return $this->error($schema, $context, 'contentEncoding', "The value must be encoded as '{encoding}'", [ + 'encoding' => $this->name, + ]); + } + + $context->setDecodedContent($result); + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ContentMediaTypeKeyword.php b/vendor/opis/json-schema/src/Keywords/ContentMediaTypeKeyword.php new file mode 100644 index 0000000..358ebdd --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ContentMediaTypeKeyword.php @@ -0,0 +1,83 @@ +name = $name; + $this->resolver = $resolver; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if (!$this->resolver) { + return null; + } + + if ($this->media === false) { + $this->media = $this->resolver->resolve($this->name); + } + + if ($this->media === null) { + throw new UnresolvedContentMediaTypeException($this->name, $schema, $context); + } + + $data = $context->getDecodedContent(); + + $ok = $this->media instanceof ContentMediaType + ? $this->media->validate($data, $this->name) + : ($this->media)($data, $this->name); + if ($ok) { + return null; + } + + unset($data); + + return $this->error($schema, $context, 'contentMediaType', "The media type of the data must be '{media}'", [ + 'media' => $this->name, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ContentSchemaKeyword.php b/vendor/opis/json-schema/src/Keywords/ContentSchemaKeyword.php new file mode 100644 index 0000000..01b3cc7 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ContentSchemaKeyword.php @@ -0,0 +1,64 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $data = json_decode($context->getDecodedContent(), false); + + if ($error = json_last_error() !== JSON_ERROR_NONE) { + $message = json_last_error_msg(); + + return $this->error($schema, $context, 'contentSchema', "Invalid JSON content: {message}", [ + 'error' => $error, + 'message' => $message, + ]); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + if ($error = $this->value->validate($context->newInstance($data, $schema))) { + return $this->error($schema, $context, 'contentSchema', "The JSON content must match schema", [], $error); + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/DefaultKeyword.php b/vendor/opis/json-schema/src/Keywords/DefaultKeyword.php new file mode 100644 index 0000000..afaa727 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/DefaultKeyword.php @@ -0,0 +1,53 @@ +defaults = $defaults; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $data = $context->currentData(); + + if (is_object($data)) { + foreach ($this->defaults as $name => $value) { + if (!property_exists($data, $name)) { + $data->{$name} = Helper::cloneValue($value); + } + } + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/DependenciesKeyword.php b/vendor/opis/json-schema/src/Keywords/DependenciesKeyword.php new file mode 100644 index 0000000..15216aa --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/DependenciesKeyword.php @@ -0,0 +1,95 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $data = $context->currentData(); + $object = $this->createArrayObject($context); + + foreach ($this->value as $name => $value) { + if ($value === true || !property_exists($data, $name)) { + continue; + } + + if ($value === false) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'dependencies', "Property '{property}' is not allowed", [ + 'property' => $name, + ]); + } + + if (is_array($value)) { + foreach ($value as $prop) { + if (!property_exists($data, $prop)) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'dependencies', + "Property '{missing}' property is required by property '{property}'", [ + 'property' => $name, + 'missing' => $prop, + ]); + } + } + + continue; + } + + if (is_object($value) && !($value instanceof Schema)) { + $value = $this->value[$name] = $context->loader()->loadObjectSchema($value); + } + + if ($error = $context->validateSchemaWithoutEvaluated($value, null, false, $object)) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'dependencies', + "The object must match dependency schema defined on property '{property}'", [ + 'property' => $name, + ], $error); + } + } + + $this->addEvaluatedFromArrayObject($object, $context); + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/DependentRequiredKeyword.php b/vendor/opis/json-schema/src/Keywords/DependentRequiredKeyword.php new file mode 100644 index 0000000..90b6188 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/DependentRequiredKeyword.php @@ -0,0 +1,66 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $data = $context->currentData(); + + foreach ($this->value as $name => $value) { + if (!property_exists($data, $name)) { + continue; + } + foreach ($value as $prop) { + if (!property_exists($data, $prop)) { + return $this->error($schema, $context, 'dependentRequired', + "'{$prop}' property is required by '{$name}' property", [ + 'property' => $name, + 'missing' => $prop, + ]); + } + } + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/DependentSchemasKeyword.php b/vendor/opis/json-schema/src/Keywords/DependentSchemasKeyword.php new file mode 100644 index 0000000..1714bb1 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/DependentSchemasKeyword.php @@ -0,0 +1,76 @@ +value = (array)$value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $data = $context->currentData(); + $object = $this->createArrayObject($context); + + foreach ($this->value as $name => $value) { + if ($value === true || !property_exists($data, $name)) { + continue; + } + + if ($value === false) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'dependentSchemas', "'{$name}' property is not allowed", [ + 'property' => $name, + ]); + } + + if (is_object($value) && !($value instanceof Schema)) { + $value = $this->value[$name] = $context->loader()->loadObjectSchema($value); + } + + if ($error = $context->validateSchemaWithoutEvaluated($value, null, false, $object)) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'dependentSchemas', + "The object must match dependency schema defined on property '{$name}'", [ + 'property' => $name, + ], $error); + } + } + + $this->addEvaluatedFromArrayObject($object, $context); + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/EnumDataKeyword.php b/vendor/opis/json-schema/src/Keywords/EnumDataKeyword.php new file mode 100644 index 0000000..6e2707e --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/EnumDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct([]); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $value = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + if ($value === $this || !is_array($value) || empty($value)) { + return $this->error($schema, $context, 'enum', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->enum = $this->listByType($value); + $ret = parent::validate($context, $schema); + $this->enum = null; + + return $ret; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/EnumKeyword.php b/vendor/opis/json-schema/src/Keywords/EnumKeyword.php new file mode 100644 index 0000000..92b0a0d --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/EnumKeyword.php @@ -0,0 +1,79 @@ +enum = $this->listByType($enum); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $type = $context->currentDataType(); + $data = $context->currentData(); + + if (isset($this->enum[$type])) { + foreach ($this->enum[$type] as $value) { + if (Helper::equals($value, $data)) { + return null; + } + } + } + + return $this->error($schema, $context, 'enum', 'The data should match one item from enum'); + } + + /** + * @param array $values + * @return array + */ + protected function listByType(array $values): array + { + $list = []; + + foreach ($values as $value) { + $type = Helper::getJsonType($value); + if (!isset($list[$type])) { + $list[$type] = []; + } + $list[$type][] = $value; + } + + return $list; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ErrorTrait.php b/vendor/opis/json-schema/src/Keywords/ErrorTrait.php new file mode 100644 index 0000000..8d78360 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ErrorTrait.php @@ -0,0 +1,55 @@ +all(); + } + } + + return new ValidationError($keyword, $schema, DataInfo::fromContext($context), $message, $args, + is_array($errors) ? $errors : []); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ExclusiveMaximumDataKeyword.php b/vendor/opis/json-schema/src/Keywords/ExclusiveMaximumDataKeyword.php new file mode 100644 index 0000000..056c6f8 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ExclusiveMaximumDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var float|int $number */ + $number = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($number === $this || !(is_float($number) || is_int($number))) { + return $this->error($schema, $context, 'exclusiveMaximum', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->number = $number; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ExclusiveMaximumKeyword.php b/vendor/opis/json-schema/src/Keywords/ExclusiveMaximumKeyword.php new file mode 100644 index 0000000..66ecd61 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ExclusiveMaximumKeyword.php @@ -0,0 +1,50 @@ +number = $number; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($context->currentData() < $this->number) { + return null; + } + + return $this->error($schema, $context, 'exclusiveMaximum', "Number must be lower than {max}", [ + 'max' => $this->number, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ExclusiveMinimumDataKeyword.php b/vendor/opis/json-schema/src/Keywords/ExclusiveMinimumDataKeyword.php new file mode 100644 index 0000000..92635ae --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ExclusiveMinimumDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var float|int $number */ + $number = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($number === $this || !(is_float($number) || is_int($number))) { + return $this->error($schema, $context, 'exclusiveMinimum', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->number = $number; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ExclusiveMinimumKeyword.php b/vendor/opis/json-schema/src/Keywords/ExclusiveMinimumKeyword.php new file mode 100644 index 0000000..90a85f5 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ExclusiveMinimumKeyword.php @@ -0,0 +1,50 @@ +number = $number; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($context->currentData() > $this->number) { + return null; + } + + return $this->error($schema, $context, 'exclusiveMinimum', "Number must be greater than {min}", [ + 'min' => $this->number, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/FiltersKeyword.php b/vendor/opis/json-schema/src/Keywords/FiltersKeyword.php new file mode 100644 index 0000000..e85b961 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/FiltersKeyword.php @@ -0,0 +1,93 @@ +filters = $filters; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $type = $context->currentDataType(); + + foreach ($this->filters as $filter) { + if (!isset($filter->types[$type])) { + throw new UnresolvedFilterException($filter->name, $type, $schema, $context); + } + + $func = $filter->types[$type]; + + if ($filter->args) { + $args = (array)$filter->args->resolve($context->rootData(), $context->currentDataPath()); + $args += $context->globals(); + } else { + $args = $context->globals(); + } + + try { + if ($func instanceof Filter) { + $ok = $func->validate($context, $schema, $args); + } else { + $ok = $func($context->currentData(), $args); + } + } catch (CustomError $error) { + return $this->error($schema, $context, '$filters', $error->getMessage(), $error->getArgs() + [ + 'filter' => $filter->name, + 'type' => $type, + 'args' => $args, + ]); + } + + if ($ok) { + unset($func, $args, $ok); + continue; + } + + return $this->error($schema, $context, '$filters', "Filter '{filter}' ({type}) was not passed", [ + 'filter' => $filter->name, + 'type' => $type, + 'args' => $args, + ]); + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/FormatDataKeyword.php b/vendor/opis/json-schema/src/Keywords/FormatDataKeyword.php new file mode 100644 index 0000000..105baa2 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/FormatDataKeyword.php @@ -0,0 +1,76 @@ +value = $value; + $this->resolver = $resolver; + parent::__construct('', []); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $value = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + if ($value === $this || !is_string($value)) { + return $this->error($schema, $context, 'format', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + /** @var string $value */ + + $type = $context->currentDataType(); + + $types = [ + $type => $this->resolver->resolve($value, $type), + ]; + + if (!$types[$type] && ($super = Helper::getJsonSuperType($type))) { + $types[$super] = $this->resolver->resolve($value, $super); + unset($super); + } + + unset($type); + + $this->name = $value; + $this->types = $types; + $ret = parent::validate($context, $schema); + $this->name = $this->types = null; + + return $ret; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/FormatKeyword.php b/vendor/opis/json-schema/src/Keywords/FormatKeyword.php new file mode 100644 index 0000000..3693809 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/FormatKeyword.php @@ -0,0 +1,82 @@ +name = $name; + $this->types = $types; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $type = $context->currentDataType(); + + if (!isset($this->types[$type])) { + return null; + } + + $format = $this->types[$type]; + + try { + if ($format instanceof Format) { + $ok = $format->validate($context->currentData()); + } else { + $ok = $format($context->currentData()); + } + } catch (CustomError $error) { + return $this->error($schema, $context, 'format', $error->getMessage(), $error->getArgs() + [ + 'format' => $this->name, + 'type' => $type, + ]); + } + + if ($ok) { + return null; + } + + return $this->error($schema, $context, 'format', "The data must match the '{format}' format", [ + 'format' => $this->name, + 'type' => $type, + ]); + } +} diff --git a/vendor/opis/json-schema/src/Keywords/IfThenElseKeyword.php b/vendor/opis/json-schema/src/Keywords/IfThenElseKeyword.php new file mode 100644 index 0000000..730ac68 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/IfThenElseKeyword.php @@ -0,0 +1,104 @@ +if = $if; + $this->then = $then; + $this->else = $else; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->if === true) { + return $this->validateBranch('then', $context, $schema); + } elseif ($this->if === false) { + return $this->validateBranch('else', $context, $schema); + } + + if (is_object($this->if) && !($this->if instanceof Schema)) { + $this->if = $context->loader()->loadObjectSchema($this->if); + } + + if ($context->validateSchemaWithoutEvaluated($this->if, null, true)) { + return $this->validateBranch('else', $context, $schema); + } + + return $this->validateBranch('then', $context, $schema); + } + + /** + * @param string $branch + * @param ValidationContext $context + * @param Schema $schema + * @return ValidationError|null + */ + protected function validateBranch(string $branch, ValidationContext $context, Schema $schema): ?ValidationError + { + $value = $this->{$branch}; + + if ($value === true) { + return null; + } elseif ($value === false) { + return $this->error($schema, $context, $branch, "The data is never valid on '{branch}' branch", [ + 'branch' => $branch, + ]); + } + + if (is_object($value) && !($value instanceof Schema)) { + $value = $this->{$branch} = $context->loader()->loadObjectSchema($value); + } + + if ($error = $value->validate($context)) { + return $this->error($schema, $context, $branch, "The data is not valid on '{branch}' branch", [ + 'branch' => $branch, + ], $error); + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/ItemsKeyword.php b/vendor/opis/json-schema/src/Keywords/ItemsKeyword.php new file mode 100644 index 0000000..4726455 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/ItemsKeyword.php @@ -0,0 +1,162 @@ +value = $value; + $this->alwaysValid = $alwaysValid; + + if (is_array($value)) { + $this->count = count($value); + } + + $this->keyword = $keyword; + $this->startIndex = $startIndex; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->alwaysValid || $this->value === true) { + if ($this->count === -1) { + $context->markAllAsEvaluatedItems(); + } else { + $context->markCountAsEvaluatedItems($this->count); + } + return null; + } + + $count = count($context->currentData()); + + if ($this->startIndex >= $count) { + // Already validated by other keyword + return null; + } + + if ($this->value === false) { + if ($count === 0) { + return null; + } + + return $this->error($schema, $context, $this->keyword, 'Array must be empty'); + } + + if ($this->count >= 0) { + + $errors = $this->errorContainer($context->maxErrors()); + $max = min($count, $this->count); + $evaluated = []; + + for ($i = $this->startIndex; $i < $max; $i++) { + if ($this->value[$i] === true) { + $evaluated[] = $i; + continue; + } + + if ($this->value[$i] === false) { + $context->addEvaluatedItems($evaluated); + return $this->error($schema, $context, $this->keyword, "Array item at index {index} is not allowed", [ + 'index' => $i, + ]); + } + + if (is_object($this->value[$i]) && !($this->value[$i] instanceof Schema)) { + $this->value[$i] = $context->loader()->loadObjectSchema($this->value[$i]); + } + + $context->pushDataPath($i); + $error = $this->value[$i]->validate($context); + $context->popDataPath(); + + if ($error) { + $errors->add($error); + if ($errors->isFull()) { + break; + } + } else { + $evaluated[] = $i; + } + } + + $context->addEvaluatedItems($evaluated); + + if ($errors->isEmpty()) { + return null; + } + + return $this->error($schema, $context, $this->keyword, 'Array items must match corresponding schemas', [], + $errors); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + $object = $this->createArrayObject($context); + + $error = $this->validateIterableData($schema, $this->value, $context, $this->indexes($this->startIndex, $count), + $this->keyword, 'All array items must match schema', [], $object); + + if ($object && $object->count()) { + $context->addEvaluatedItems($object->getArrayCopy()); + } + + return $error; + } + + /** + * @param int $start + * @param int $max + * @return iterable|int[] + */ + protected function indexes(int $start, int $max): iterable + { + for ($i = $start; $i < $max; $i++) { + yield $i; + } + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/IterableDataValidationTrait.php b/vendor/opis/json-schema/src/Keywords/IterableDataValidationTrait.php new file mode 100644 index 0000000..99754ec --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/IterableDataValidationTrait.php @@ -0,0 +1,110 @@ +errorContainer($context->maxErrors()); + + if ($keys) { + foreach ($iterator as $key) { + $context->pushDataPath($key); + $error = $schema->validate($context); + $context->popDataPath(); + + if ($error) { + if (!$container->isFull()) { + $container->add($error); + } + } else { + $keys[] = $key; + } + } + } else { + foreach ($iterator as $key) { + $context->pushDataPath($key); + $error = $schema->validate($context); + $context->popDataPath(); + + if ($error && $container->add($error)->isFull()) { + break; + } + } + } + + return $container; + } + + /** + * @param Schema $parentSchema + * @param Schema $schema + * @param ValidationContext $context + * @param iterable $iterator + * @param string $keyword + * @param string $message + * @param array $args + * @param ArrayObject|null $visited_keys + * @return ValidationError|null + */ + protected function validateIterableData( + Schema $parentSchema, + Schema $schema, + ValidationContext $context, + iterable $iterator, + string $keyword, + string $message, + array $args = [], + ?ArrayObject $visited_keys = null + ): ?ValidationError { + $errors = $this->iterateAndValidate($schema, $context, $iterator, $visited_keys); + + if ($errors->isEmpty()) { + return null; + } + + return $this->error($parentSchema, $context, $keyword, $message, $args, $errors); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MaxItemsDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MaxItemsDataKeyword.php new file mode 100644 index 0000000..7e53797 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MaxItemsDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var int $count */ + $count = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($count === $this || !is_int($count) || $count < 0) { + return $this->error($schema, $context, 'maxItems', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->count = $count; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MaxItemsKeyword.php b/vendor/opis/json-schema/src/Keywords/MaxItemsKeyword.php new file mode 100644 index 0000000..4003d2f --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MaxItemsKeyword.php @@ -0,0 +1,58 @@ +count = $count; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $count = count($context->currentData()); + + if ($count <= $this->count) { + return null; + } + + return $this->error($schema, $context, "maxItems", + "Array should have at most {max} items, {count} found", [ + 'max' => $this->count, + 'count' => $count, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MaxLengthDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MaxLengthDataKeyword.php new file mode 100644 index 0000000..ea2366d --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MaxLengthDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var int $length */ + $length = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($length === $this || !is_int($length) || $length < 0) { + return $this->error($schema, $context, 'maxLength', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->length = $length; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MaxLengthKeyword.php b/vendor/opis/json-schema/src/Keywords/MaxLengthKeyword.php new file mode 100644 index 0000000..3afa2b3 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MaxLengthKeyword.php @@ -0,0 +1,62 @@ +length = $length; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->length === 0) { + return null; + } + + $length = $context->getStringLength(); + + if ($length <= $this->length) { + return null; + } + + return $this->error($schema, $context, 'maxLength', "Maximum string length is {max}, found {length}", + [ + 'max' => $this->length, + 'length' => $length, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MaxPropertiesDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MaxPropertiesDataKeyword.php new file mode 100644 index 0000000..f48f439 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MaxPropertiesDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var int $count */ + $count = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($count === $this || !is_int($count) || $count < 0) { + return $this->error($schema, $context, 'maxProperties', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->count = $count; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MaxPropertiesKeywords.php b/vendor/opis/json-schema/src/Keywords/MaxPropertiesKeywords.php new file mode 100644 index 0000000..34fa0d6 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MaxPropertiesKeywords.php @@ -0,0 +1,58 @@ +count = $count; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $count = count($context->getObjectProperties()); + + if ($count <= $this->count) { + return null; + } + + return $this->error($schema, $context, 'maxProperties', + "Object must have at most {max} properties, {count} found", [ + 'max' => $this->count, + 'count' => $count, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MaximumDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MaximumDataKeyword.php new file mode 100644 index 0000000..55b9dfd --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MaximumDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var float|int $number */ + $number = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($number === $this || !(is_float($number) || is_int($number))) { + return $this->error($schema, $context, 'maximum', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->number = $number; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MaximumKeyword.php b/vendor/opis/json-schema/src/Keywords/MaximumKeyword.php new file mode 100644 index 0000000..6888a27 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MaximumKeyword.php @@ -0,0 +1,54 @@ +number = $number; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($context->currentData() <= $this->number) { + return null; + } + + return $this->error($schema, $context, 'maximum', "Number must be lower than or equal to {max}", [ + 'max' => $this->number, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MinItemsDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MinItemsDataKeyword.php new file mode 100644 index 0000000..1ace7fd --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MinItemsDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var int $count */ + $count = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($count === $this || !is_int($count) || $count < 0) { + return $this->error($schema, $context, 'minItems', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->count = $count; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MinItemsKeyword.php b/vendor/opis/json-schema/src/Keywords/MinItemsKeyword.php new file mode 100644 index 0000000..bcc0d83 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MinItemsKeyword.php @@ -0,0 +1,58 @@ +count = $count; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $count = count($context->currentData()); + + if ($count >= $this->count) { + return null; + } + + return $this->error($schema, $context, "minItems", + "Array should have at least {min} items, {count} found", [ + 'min' => $this->count, + 'count' => $count, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MinLengthDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MinLengthDataKeyword.php new file mode 100644 index 0000000..57d78c8 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MinLengthDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var int $length */ + $length = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($length === $this || !is_int($length) || $length < 0) { + return $this->error($schema, $context, 'minLength', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->length = $length; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MinLengthKeyword.php b/vendor/opis/json-schema/src/Keywords/MinLengthKeyword.php new file mode 100644 index 0000000..7c446d0 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MinLengthKeyword.php @@ -0,0 +1,61 @@ +length = $length; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->length === 0) { + return null; + } + + $length = $context->getStringLength(); + + if ($length >= $this->length) { + return null; + } + + return $this->error($schema, $context, 'minLength', "Minimum string length is {min}, found {length}", [ + 'min' => $this->length, + 'length' => $length, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MinPropertiesDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MinPropertiesDataKeyword.php new file mode 100644 index 0000000..e1b2a2d --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MinPropertiesDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var int $count */ + $count = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($count === $this || !is_int($count) || $count < 0) { + return $this->error($schema, $context, 'minProperties', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->count = $count; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MinPropertiesKeyword.php b/vendor/opis/json-schema/src/Keywords/MinPropertiesKeyword.php new file mode 100644 index 0000000..7836168 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MinPropertiesKeyword.php @@ -0,0 +1,58 @@ +count = $count; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $count = count($context->getObjectProperties()); + + if ($this->count <= $count) { + return null; + } + + return $this->error($schema, $context, 'minProperties', + "Object must have at least {min} properties, {count} found", [ + 'min' => $this->count, + 'count' => $count, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MinimumDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MinimumDataKeyword.php new file mode 100644 index 0000000..37140c3 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MinimumDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var float|int $number */ + $number = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($number === $this || !(is_float($number) || is_int($number))) { + return $this->error($schema, $context, 'minimum', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->number = $number; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MinimumKeyword.php b/vendor/opis/json-schema/src/Keywords/MinimumKeyword.php new file mode 100644 index 0000000..a499aef --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MinimumKeyword.php @@ -0,0 +1,54 @@ +number = $number; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($context->currentData() >= $this->number) { + return null; + } + + return $this->error($schema, $context, 'minimum', "Number must be greater than or equal to {min}", [ + 'min' => $this->number, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MultipleOfDataKeyword.php b/vendor/opis/json-schema/src/Keywords/MultipleOfDataKeyword.php new file mode 100644 index 0000000..532ee8a --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MultipleOfDataKeyword.php @@ -0,0 +1,55 @@ +value = $value; + parent::__construct(0); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + /** @var float|int $number */ + $number = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($number === $this || !(is_float($number) || is_int($number)) || $number <= 0) { + return $this->error($schema, $context, 'multipleOf', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->number = $number; + + return parent::validate($context, $schema); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/MultipleOfKeyword.php b/vendor/opis/json-schema/src/Keywords/MultipleOfKeyword.php new file mode 100644 index 0000000..28ac8f6 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/MultipleOfKeyword.php @@ -0,0 +1,55 @@ +number = $number; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if (Helper::isMultipleOf($context->currentData(), $this->number)) { + return null; + } + + return $this->error($schema, $context, 'multipleOf', "Number must be a multiple of {divisor}", [ + 'divisor' => $this->number, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/NotKeyword.php b/vendor/opis/json-schema/src/Keywords/NotKeyword.php new file mode 100644 index 0000000..3a5acd4 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/NotKeyword.php @@ -0,0 +1,66 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->value === false) { + return null; + } + if ($this->value === true) { + return $this->error($schema, $context, 'not', "The data is never valid"); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + $error = $context->validateSchemaWithoutEvaluated($this->value, 1); + + if ($error) { + return null; + } + + return $this->error($schema, $context, 'not', 'The data must not match schema'); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/OfTrait.php b/vendor/opis/json-schema/src/Keywords/OfTrait.php new file mode 100644 index 0000000..bcb0b2c --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/OfTrait.php @@ -0,0 +1,45 @@ +trackUnevaluated() ? new ArrayObject() : null; + } + + protected function addEvaluatedFromArrayObject(?ArrayObject $object, ValidationContext $context): void + { + if (!$object || !$object->count()) { + return; + } + + foreach ($object as $value) { + if (isset($value['properties'])) { + $context->addEvaluatedProperties($value['properties']); + } + if (isset($value['items'])) { + $context->addEvaluatedItems($value['items']); + } + } + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/OneOfKeyword.php b/vendor/opis/json-schema/src/Keywords/OneOfKeyword.php new file mode 100644 index 0000000..12473b6 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/OneOfKeyword.php @@ -0,0 +1,98 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $count = 0; + $matchedIndex = -1; + $object = $this->createArrayObject($context); + $errors = []; + + foreach ($this->value as $index => $value) { + if ($value === false) { + continue; + } + + if ($value === true) { + if (++$count > 1) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'oneOf', 'The data should match exactly one schema', [ + 'matched' => [$matchedIndex, $index], + ]); + } + + $matchedIndex = $index; + continue; + } + + if (is_object($value) && !($value instanceof Schema)) { + $value = $this->value[$index] = $context->loader()->loadObjectSchema($value); + } + + $error = $context->validateSchemaWithoutEvaluated($value, null, false, $object); + if ($error) { + $errors[] = $error; + } else { + if (++$count > 1) { + $this->addEvaluatedFromArrayObject($object, $context); + return $this->error($schema, $context, 'oneOf', 'The data should match exactly one schema', [ + 'matched' => [$matchedIndex, $index], + ]); + } + $matchedIndex = $index; + } + } + + $this->addEvaluatedFromArrayObject($object, $context); + + if ($count === 1) { + return null; + } + + return $this->error($schema, $context, 'oneOf', 'The data should match exactly one schema', [ + 'matched' => [], + ], $errors); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/PatternDataKeyword.php b/vendor/opis/json-schema/src/Keywords/PatternDataKeyword.php new file mode 100644 index 0000000..1fa7c15 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/PatternDataKeyword.php @@ -0,0 +1,56 @@ +value = $value; + parent::__construct(''); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $pattern = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + if ($pattern === $this || !is_string($pattern) || !Helper::isValidPattern($pattern)) { + return $this->error($schema, $context, 'pattern', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $this->pattern = $pattern; + $this->regex = Helper::patternToRegex($pattern); + $ret = parent::validate($context, $schema); + $this->pattern = $this->regex = null; + + return $ret; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/PatternKeyword.php b/vendor/opis/json-schema/src/Keywords/PatternKeyword.php new file mode 100644 index 0000000..b16cbc1 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/PatternKeyword.php @@ -0,0 +1,53 @@ +pattern = $pattern; + $this->regex = Helper::patternToRegex($pattern); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if (preg_match($this->regex, $context->currentData())) { + return null; + } + + return $this->error($schema, $context, 'pattern', "The string should match pattern: {pattern}", [ + 'pattern' => $this->pattern, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/PatternPropertiesKeyword.php b/vendor/opis/json-schema/src/Keywords/PatternPropertiesKeyword.php new file mode 100644 index 0000000..7980a85 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/PatternPropertiesKeyword.php @@ -0,0 +1,119 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $props = $context->getObjectProperties(); + + if (!$props) { + return null; + } + + $checked = []; + + foreach ($this->value as $pattern => $value) { + if ($value === true) { + iterator_to_array($this->matchedProperties($pattern, $props, $checked)); + continue; + } + + if ($value === false) { + $list = iterator_to_array($this->matchedProperties($pattern, $props, $checked)); + + if ($list) { + if ($context->trackUnevaluated()) { + $context->addEvaluatedProperties(array_diff(array_keys($checked), $list)); + } + return $this->error($schema, $context, 'patternProperties', "Object properties that match pattern '{pattern}' are not allowed", [ + 'pattern' => $pattern, + 'forbidden' => $list, + ]); + } + + unset($list); + continue; + } + + if (is_object($value) && !($value instanceof Schema)) { + $value = $this->value[$pattern] = $context->loader()->loadObjectSchema($value); + } + + $subErrors = $this->iterateAndValidate($value, $context, $this->matchedProperties($pattern, $props, $checked)); + + if (!$subErrors->isEmpty()) { + if ($context->trackUnevaluated()) { + $context->addEvaluatedProperties(array_keys($checked)); + } + return $this->error($schema, $context, 'patternProperties', "Object properties that match pattern '{pattern}' must also match pattern's schema", [ + 'pattern' => $pattern, + ], $subErrors); + } + + unset($subErrors); + } + + if ($checked) { + $checked = array_keys($checked); + $context->addCheckedProperties($checked); + $context->addEvaluatedProperties($checked); + } + + return null; + } + + /** + * @param string $pattern + * @param array $props + * @param array $checked + * @return Traversable|string[] + */ + protected function matchedProperties(string $pattern, array $props, array &$checked): Traversable + { + $pattern = Helper::patternToRegex($pattern); + + foreach ($props as $prop) { + if (preg_match($pattern, (string)$prop)) { + $checked[$prop] = true; + yield $prop; + } + } + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/PointerRefKeyword.php b/vendor/opis/json-schema/src/Keywords/PointerRefKeyword.php new file mode 100644 index 0000000..a11142b --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/PointerRefKeyword.php @@ -0,0 +1,54 @@ +pointer = $pointer; + } + + protected function doValidate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->resolved === false) { + $info = $schema->info(); + $this->resolved = $this->resolvePointer($context->loader(), $this->pointer, $info->idBaseRoot(), $info->path()); + } + + if ($this->resolved === null) { + throw new UnresolvedReferenceException((string)$this->pointer, $schema, $context); + } + + return $this->resolved->validate($this->createContext($context, $schema)); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/PropertiesKeyword.php b/vendor/opis/json-schema/src/Keywords/PropertiesKeyword.php new file mode 100644 index 0000000..5af6557 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/PropertiesKeyword.php @@ -0,0 +1,109 @@ +properties = $properties; + $this->propertyKeys = array_keys($properties); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if (!$this->properties) { + return null; + } + + $checked = []; + $evaluated = []; + + $data = $context->currentData(); + + $errors = $this->errorContainer($context->maxErrors()); + + foreach ($this->properties as $name => $prop) { + if (!property_exists($data, $name)) { + continue; + } + + $checked[] = $name; + + if ($prop === true) { + $evaluated[] = $name; + continue; + } + + if ($prop === false) { + $context->addEvaluatedProperties($evaluated); + return $this->error($schema, $context, 'properties', "Property '{property}' is not allowed", [ + 'property' => $name, + ]); + } + + if (is_object($prop) && !($prop instanceof Schema)) { + $prop = $this->properties[$name] = $context->loader()->loadObjectSchema($prop); + } + + $context->pushDataPath($name); + $error = $prop->validate($context); + $context->popDataPath(); + + if ($error) { + $errors->add($error); + if ($errors->isFull()) { + break; + } + } else { + $evaluated[] = $name; + } + } + + $context->addEvaluatedProperties($evaluated); + + if (!$errors->isEmpty()) { + return $this->error($schema, $context, 'properties', "The properties must match schema: {properties}", [ + 'properties' => array_values(array_diff($checked, $evaluated)) + ], $errors); + } + unset($errors); + + $context->addCheckedProperties($checked); + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/PropertyNamesKeyword.php b/vendor/opis/json-schema/src/Keywords/PropertyNamesKeyword.php new file mode 100644 index 0000000..4012ca9 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/PropertyNamesKeyword.php @@ -0,0 +1,74 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->value === true) { + return null; + } + + $props = $context->getObjectProperties(); + if (!$props) { + return null; + } + + if ($this->value === false) { + return $this->error($schema, $context, 'propertyNames', "No properties are allowed"); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + foreach ($props as $prop) { + if ($error = $this->value->validate($context->newInstance($prop, $schema))) { + return $this->error($schema, $context, 'propertyNames', "Property '{property}' must match schema", [ + 'property' => $prop, + ], $error); + } + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/RecursiveRefKeyword.php b/vendor/opis/json-schema/src/Keywords/RecursiveRefKeyword.php new file mode 100644 index 0000000..d460001 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/RecursiveRefKeyword.php @@ -0,0 +1,138 @@ +uri = $uri; + $this->anchor = $anchor; + $this->anchorValue = $anchorValue; + } + + /** + * @inheritDoc + */ + public function doValidate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->resolved === false) { + $this->resolved = $context->loader()->loadSchemaById($this->uri); + } + + if ($this->resolved === null) { + throw new UnresolvedReferenceException((string)$this->uri, $schema, $context); + } + + $new_context = $this->createContext($context, $schema); + + if (!$this->hasRecursiveAnchor($this->resolved)) { + $this->setLastRefSchema($this->resolved); + return $this->resolved->validate($new_context); + } + + $ok_sender = $this->resolveSchema($context); + + if (!$ok_sender) { + $this->setLastRefSchema($this->resolved); + return $this->resolved->validate($new_context); + } + + $this->setLastRefSchema($ok_sender); + + return $ok_sender->validate($new_context); + } + + protected function resolveSchema(ValidationContext $context): ?Schema + { + $ok = null; + $loader = $context->loader(); + + while ($context) { + $sender = $context->sender(); + + if (!$sender) { + break; + } + + if (!$this->hasRecursiveAnchor($sender)) { + if ($sender->info()->id()) { + // id without recursiveAnchor + break; + } + + $sender = $loader->loadSchemaById($sender->info()->root()); + if (!$sender || !$this->hasRecursiveAnchor($sender)) { + // root without recursiveAnchor + break; + } + } + + if ($sender->info()->id()) { + // id with recursiveAnchor + $ok = $sender; + } else { + // root with recursiveAnchor + $ok = $loader->loadSchemaById($sender->info()->root()); + } + + $context = $context->parent(); + } + + return $ok; + } + + protected function hasRecursiveAnchor(?Schema $schema): bool + { + if (!$schema) { + return false; + } + + $info = $schema->info(); + + if (!$info->isObject()) { + return false; + } + + $data = $info->data(); + + if (!property_exists($data, $this->anchor)) { + return false; + } + + return $data->{$this->anchor} === $this->anchorValue; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/RequiredDataKeyword.php b/vendor/opis/json-schema/src/Keywords/RequiredDataKeyword.php new file mode 100644 index 0000000..d518244 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/RequiredDataKeyword.php @@ -0,0 +1,85 @@ +value = $value; + $this->filter = $filter; + parent::__construct([]); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $required = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + if ($required === $this || !is_array($required) || !$this->requiredPropsAreValid($required)) { + return $this->error($schema, $context, 'required', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + $required = array_unique($required); + + if ($this->filter) { + $required = array_filter($required, $this->filter); + } + + if (!$required) { + return null; + } + + $this->required = $required; + $ret = parent::validate($context, $schema); + $this->required = null; + + return $ret; + } + + /** + * @param array $props + * @return bool + */ + protected function requiredPropsAreValid(array $props): bool + { + foreach ($props as $prop) { + if (!is_string($prop)) { + return false; + } + } + + return true; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/RequiredKeyword.php b/vendor/opis/json-schema/src/Keywords/RequiredKeyword.php new file mode 100644 index 0000000..005e2dc --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/RequiredKeyword.php @@ -0,0 +1,68 @@ +required = $required; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $data = $context->currentData(); + $max = $context->maxErrors(); + $list = []; + + foreach ($this->required as $name) { + if (!property_exists($data, $name)) { + $list[] = $name; + if (--$max <= 0) { + break; + } + } + } + + if (!$list) { + return null; + } + + return $this->error($schema, $context, 'required', 'The required properties ({missing}) are missing', [ + 'missing' => $list, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/SlotsKeyword.php b/vendor/opis/json-schema/src/Keywords/SlotsKeyword.php new file mode 100644 index 0000000..c843845 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/SlotsKeyword.php @@ -0,0 +1,151 @@ +slots = $slots; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $newContext = $context->newInstance($context->currentData(), $schema); + + foreach ($this->slots as $name => $fallback) { + $slot = $this->resolveSlotSchema($name, $context); + + if ($slot === null) { + $save = true; + if (is_string($fallback)) { + $save = false; + $fallback = $this->resolveSlot($fallback, $context); + } + + if ($fallback === true) { + continue; + } + + if ($fallback === false) { + return $this->error($schema, $context, '$slots', "Required slot '{slot}' is missing", [ + 'slot' => $name, + ]); + } + + if (is_object($fallback) && !($fallback instanceof Schema)) { + $fallback = $context->loader()->loadObjectSchema($fallback); + if ($save) { + $this->slots[$name] = $fallback; + } + } + + $slot = $fallback; + } + + if ($error = $slot->validate($newContext)) { + return $this->error($schema, $context,'$slots', "Schema for slot '{slot}' was not matched", [ + 'slot' => $name, + ], $error); + } + } + + return null; + } + + /** + * @param string $name + * @param ValidationContext $context + * @return Schema|null + */ + protected function resolveSlotSchema(string $name, ValidationContext $context): ?Schema + { + do { + $slot = $context->slot($name); + } while ($slot === null && $context = $context->parent()); + + return $slot; + } + + /** + * @param string $name + * @param ValidationContext $context + * @return bool|Schema + */ + protected function resolveSlot(string $name, ValidationContext $context) + { + $slot = $this->resolveSlotSchema($name, $context); + + if ($slot !== null) { + return $slot; + } + + if (!isset($this->slots[$name])) { + return false; + } + + $slot = $this->slots[$name]; + + if (is_bool($slot)) { + return $slot; + } + + if (is_object($slot)) { + if ($slot instanceof Schema) { + return $slot; + } + + $slot = $context->loader()->loadObjectSchema($slot); + $this->slots[$name] = $slot; + return $slot; + } + + if (!is_string($slot)) { + // Looks like the slot is missing + return false; + } + + if (in_array($slot, $this->stack)) { + // Recursive + return false; + } + + $this->stack[] = $slot; + $slot = $this->resolveSlot($slot, $context); + array_pop($this->stack); + + return $slot; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/TemplateRefKeyword.php b/vendor/opis/json-schema/src/Keywords/TemplateRefKeyword.php new file mode 100644 index 0000000..d9876e2 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/TemplateRefKeyword.php @@ -0,0 +1,119 @@ +template = $template; + $this->vars = $vars; + $this->allowRelativeJsonPointerInRef = $allowRelativeJsonPointerInRef; + } + + protected function doValidate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->vars) { + $vars = $this->vars->resolve($context->rootData(), $context->currentDataPath()); + if (!is_array($vars)) { + $vars = (array)$vars; + } + $vars += $context->globals(); + } else { + $vars = $context->globals(); + } + + $ref = $this->template->resolve($vars); + + $key = isset($ref[32]) ? md5($ref) : $ref; + + if (!array_key_exists($key, $this->cached)) { + $this->cached[$key] = $this->resolveRef($ref, $context->loader(), $schema); + } + + $resolved = $this->cached[$key]; + unset($key); + + if (!$resolved) { + throw new UnresolvedReferenceException($ref, $schema, $context); + } + + return $resolved->validate($this->createContext($context, $schema)); + } + + /** + * @param string $ref + * @param SchemaLoader $repo + * @param Schema $schema + * @return null|Schema + */ + protected function resolveRef(string $ref, SchemaLoader $repo, Schema $schema): ?Schema + { + if ($ref === '') { + return null; + } + + $baseUri = $schema->info()->idBaseRoot(); + + if ($ref === '#') { + return $repo->loadSchemaById($baseUri); + } + + // Check if is pointer + if ($ref[0] === '#') { + if ($pointer = JsonPointer::parse(substr($ref, 1))) { + if ($pointer->isAbsolute()) { + return $this->resolvePointer($repo, $pointer, $baseUri); + } + unset($pointer); + } + } elseif ($this->allowRelativeJsonPointerInRef && ($pointer = JsonPointer::parse($ref))) { + if ($pointer->isRelative()) { + return $this->resolvePointer($repo, $pointer, $baseUri, $schema->info()->path()); + } + unset($pointer); + } + + $ref = Uri::merge($ref, $baseUri, true); + + if ($ref === null || !$ref->isAbsolute()) { + return null; + } + + return $repo->loadSchemaById($ref); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/TypeKeyword.php b/vendor/opis/json-schema/src/Keywords/TypeKeyword.php new file mode 100644 index 0000000..af4331b --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/TypeKeyword.php @@ -0,0 +1,58 @@ +type = $type; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $type = $context->currentDataType(); + if ($type && Helper::jsonTypeMatches($type, $this->type)) { + return null; + } + + return $this->error($schema, $context, 'type', 'The data ({type}) must match the type: {expected}', [ + 'expected' => $this->type, + 'type' => $type, + ]); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/URIRefKeyword.php b/vendor/opis/json-schema/src/Keywords/URIRefKeyword.php new file mode 100644 index 0000000..ab8beba --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/URIRefKeyword.php @@ -0,0 +1,55 @@ +uri = $uri; + } + + protected function doValidate(ValidationContext $context, Schema $schema): ?ValidationError + { + if ($this->resolved === false) { + $this->resolved = $context->loader()->loadSchemaById($this->uri); + } + + if ($this->resolved === null) { + throw new UnresolvedReferenceException((string)$this->uri, $schema, $context); + } + + $this->setLastRefSchema($this->resolved); + + return $this->resolved->validate($this->createContext($context, $schema)); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/UnevaluatedItemsKeyword.php b/vendor/opis/json-schema/src/Keywords/UnevaluatedItemsKeyword.php new file mode 100644 index 0000000..a9673fe --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/UnevaluatedItemsKeyword.php @@ -0,0 +1,75 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $unevaluated = $context->getUnevaluatedItems(); + + if (!$unevaluated) { + return null; + } + + if ($this->value === true) { + $context->addEvaluatedItems($unevaluated); + return null; + } + + if ($this->value === false) { + return $this->error($schema, $context, 'unevaluatedItems', + 'Unevaluated array items are not allowed: {indexes}', [ + 'indexes' => $unevaluated, + ]); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + $object = $this->createArrayObject($context); + + $error = $this->validateIterableData($schema, $this->value, $context, $unevaluated, + 'unevaluatedItems', 'All unevaluated array items must match schema: {indexes}', [ + 'indexes' => $unevaluated, + ], $object); + + if ($object && $object->count()) { + $context->addEvaluatedItems($object->getArrayCopy()); + } + + return $error; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/UnevaluatedPropertiesKeyword.php b/vendor/opis/json-schema/src/Keywords/UnevaluatedPropertiesKeyword.php new file mode 100644 index 0000000..ac1a485 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/UnevaluatedPropertiesKeyword.php @@ -0,0 +1,77 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $unevaluated = $context->getUnevaluatedProperties(); + + if (!$unevaluated) { + return null; + } + + if ($this->value === true) { + $context->addEvaluatedProperties($unevaluated); + return null; + } + + if ($this->value === false) { + return $this->error($schema, $context, 'unevaluatedProperties', + 'Unevaluated object properties not allowed: {properties}', [ + 'properties' => $unevaluated, + ]); + } + + if (is_object($this->value) && !($this->value instanceof Schema)) { + $this->value = $context->loader()->loadObjectSchema($this->value); + } + + $object = $this->createArrayObject($context); + + $error = $this->validateIterableData($schema, $this->value, $context, $unevaluated, + 'unevaluatedProperties', 'All unevaluated object properties must match schema: {properties}', [ + 'properties' => $unevaluated, + ], $object); + + + if ($object && $object->count()) { + $context->addEvaluatedProperties($object->getArrayCopy()); + } + + return $error; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/UniqueItemsDataKeyword.php b/vendor/opis/json-schema/src/Keywords/UniqueItemsDataKeyword.php new file mode 100644 index 0000000..cd860e8 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/UniqueItemsDataKeyword.php @@ -0,0 +1,51 @@ +value = $value; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context, Schema $schema): ?ValidationError + { + $value = $this->value->data($context->rootData(), $context->currentDataPath(), $this); + + if ($value === $this || !is_bool($value)) { + return $this->error($schema, $context, 'uniqueItems', 'Invalid $data', [ + 'pointer' => (string)$this->value, + ]); + } + + return $value ? parent::validate($context, $schema) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Keywords/UniqueItemsKeyword.php b/vendor/opis/json-schema/src/Keywords/UniqueItemsKeyword.php new file mode 100644 index 0000000..f952c76 --- /dev/null +++ b/vendor/opis/json-schema/src/Keywords/UniqueItemsKeyword.php @@ -0,0 +1,57 @@ +currentData(); + if (!$data) { + return null; + } + + $count = count($data); + + for ($i = 0; $i < $count - 1; $i++) { + for ($j = $i + 1; $j < $count; $j++) { + if (Helper::equals($data[$i], $data[$j])) { + return $this->error($schema, $context, 'uniqueItems', 'Array must have unique items', [ + 'duplicate' => $data[$i], + 'indexes' => [$i, $j], + ]); + } + } + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/DataKeywordTrait.php b/vendor/opis/json-schema/src/Parsers/DataKeywordTrait.php new file mode 100644 index 0000000..44e0f45 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/DataKeywordTrait.php @@ -0,0 +1,59 @@ +{'$data'}) || count(get_object_vars($value)) !== 1) { + return null; + } + + return JsonPointer::parse($value->{'$data'}); + } + + /** + * @param SchemaParser $parser + * @param string|null $keyword + * @return bool + */ + protected function isDataKeywordAllowed(SchemaParser $parser, ?string $keyword = null): bool + { + if (!($enabled = $parser->option('allowDataKeyword'))) { + return false; + } + + if ($enabled === true) { + return true; + } + + if ($keyword === null) { + return false; + } + + return is_array($enabled) && in_array($keyword, $enabled); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/DefaultVocabulary.php b/vendor/opis/json-schema/src/Parsers/DefaultVocabulary.php new file mode 100644 index 0000000..d05d428 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/DefaultVocabulary.php @@ -0,0 +1,56 @@ +getKeywordParsers(); + $keywordValidators = $this->getKeywordValidatorParsers(); + $pragmas = $this->getPragmaParsers(); + + if ($extraVocabulary) { + $keywords = array_merge($keywords, $extraVocabulary->keywords()); + $keywordValidators = array_merge($keywordValidators, $extraVocabulary->keywordValidators()); + $pragmas = array_merge($pragmas, $extraVocabulary->pragmas()); + } + + array_unshift($keywords, $this->getRefKeywordParser()); + + parent::__construct($keywords, $keywordValidators, $pragmas); + } + + /** + * @return string + */ + abstract public function version(): string; + + /** + * @return bool + */ + abstract public function allowKeywordsAlongsideRef(): bool; + + /** + * @return bool + */ + abstract public function supportsAnchorId(): bool; + + /** + * @return KeywordParser + */ + abstract protected function getRefKeywordParser(): KeywordParser; + + /** + * @return KeywordParser[] + */ + abstract protected function getKeywordParsers(): array; + + /** + * @return KeywordValidatorParser[] + */ + protected function getKeywordValidatorParsers(): array + { + return []; + } + + /** + * @return PragmaParser[] + */ + protected function getPragmaParsers(): array + { + return []; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/DraftOptionTrait.php b/vendor/opis/json-schema/src/Parsers/DraftOptionTrait.php new file mode 100644 index 0000000..32014b4 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/DraftOptionTrait.php @@ -0,0 +1,43 @@ +option($option); + + if (!$value) { + return false; + } + + if ($value === true) { + return true; + } + + if (is_array($value)) { + return in_array($info->draft(), $value); + } + + return $value === $info->draft(); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Drafts/Draft06.php b/vendor/opis/json-schema/src/Parsers/Drafts/Draft06.php new file mode 100644 index 0000000..f8a4834 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Drafts/Draft06.php @@ -0,0 +1,145 @@ + '$recursiveRef', 'anchor' => '$recursiveAnchor', 'fragment' => false], + ]); + } + + /** + * @inheritDoc + */ + protected function getKeywordParsers(): array + { + return [ + // Generic + new TypeKeywordParser('type'), + new ConstKeywordParser('const'), + new EnumKeywordParser('enum'), + new FormatKeywordParser('format'), + + // String + new MinLengthKeywordParser('minLength'), + new MaxLengthKeywordParser('maxLength'), + new PatternKeywordParser("pattern"), + new ContentEncodingKeywordParser('contentEncoding'), + new ContentMediaTypeKeywordParser('contentMediaType'), + new ContentSchemaKeywordParser('contentSchema'), + + // Number + new MinimumKeywordParser('minimum', 'exclusiveMinimum'), + new MaximumKeywordParser('maximum', 'exclusiveMaximum'), + new ExclusiveMinimumKeywordParser('exclusiveMinimum'), + new ExclusiveMaximumKeywordParser('exclusiveMaximum'), + new MultipleOfKeywordParser('multipleOf'), + + // Array + new MinItemsKeywordParser('minItems'), + new MaxItemsKeywordParser('maxItems'), + new UniqueItemsKeywordParser('uniqueItems'), + new ContainsKeywordParser('contains', 'minContains', 'maxContains'), + new ItemsKeywordParser('items'), + new AdditionalItemsKeywordParser('additionalItems'), + + // Object + new MinPropertiesKeywordParser('minProperties'), + new MaxPropertiesKeywordParser('maxProperties'), + new RequiredKeywordParser('required'), + new DependenciesKeywordParser('dependencies'), // keep for draft-07 compatibility + new DependentRequiredKeywordParser('dependentRequired'), + new DependentSchemasKeywordParser('dependentSchemas'), + new PropertyNamesKeywordParser('propertyNames'), + new PropertiesKeywordParser('properties'), + new PatternPropertiesKeywordParser('patternProperties'), + new AdditionalPropertiesKeywordParser('additionalProperties'), + + // Conditionals + new IfThenElseKeywordParser('if', 'then', 'else'), + new AnyOfKeywordParser('anyOf'), + new AllOfKeywordParser('allOf'), + new OneOfKeywordParser('oneOf'), + new NotKeywordParser('not'), + + // Unevaluated + new UnevaluatedPropertiesKeywordParser('unevaluatedProperties'), + new UnevaluatedItemsKeywordParser('unevaluatedItems'), + + // Optional + new DefaultKeywordParser('default'), + ]; + } + +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Drafts/Draft202012.php b/vendor/opis/json-schema/src/Parsers/Drafts/Draft202012.php new file mode 100644 index 0000000..b4e960f --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Drafts/Draft202012.php @@ -0,0 +1,163 @@ + '$dynamicRef', 'anchor' => '$dynamicAnchor', 'fragment' => true], + ['ref' => '$recursiveRef', 'anchor' => '$recursiveAnchor', 'fragment' => false], + ]); + } + + /** + * @inheritDoc + */ + protected function getKeywordParsers(): array + { + return [ + // Generic + new TypeKeywordParser('type'), + new ConstKeywordParser('const'), + new EnumKeywordParser('enum'), + new FormatKeywordParser('format'), + + // String + new MinLengthKeywordParser('minLength'), + new MaxLengthKeywordParser('maxLength'), + new PatternKeywordParser("pattern"), + new ContentEncodingKeywordParser('contentEncoding'), + new ContentMediaTypeKeywordParser('contentMediaType'), + new ContentSchemaKeywordParser('contentSchema'), + + // Number + new MinimumKeywordParser('minimum', 'exclusiveMinimum'), + new MaximumKeywordParser('maximum', 'exclusiveMaximum'), + new ExclusiveMinimumKeywordParser('exclusiveMinimum'), + new ExclusiveMaximumKeywordParser('exclusiveMaximum'), + new MultipleOfKeywordParser('multipleOf'), + + // Array + new MinItemsKeywordParser('minItems'), + new MaxItemsKeywordParser('maxItems'), + new UniqueItemsKeywordParser('uniqueItems'), + new ContainsKeywordParser('contains', 'minContains', 'maxContains'), + new ItemsKeywordParser('prefixItems', ItemsKeywordParser::ONLY_ARRAY), + new ItemsKeywordParser('items', ItemsKeywordParser::ONLY_SCHEMA, 'prefixItems'), + // keep for draft-2019-09 compatibility + new AdditionalItemsKeywordParser('additionalItems'), + + // Object + new MinPropertiesKeywordParser('minProperties'), + new MaxPropertiesKeywordParser('maxProperties'), + new RequiredKeywordParser('required'), + new DependenciesKeywordParser('dependencies'), // keep for draft-07 compatibility + new DependentRequiredKeywordParser('dependentRequired'), + new DependentSchemasKeywordParser('dependentSchemas'), + new PropertyNamesKeywordParser('propertyNames'), + new PropertiesKeywordParser('properties'), + new PatternPropertiesKeywordParser('patternProperties'), + new AdditionalPropertiesKeywordParser('additionalProperties'), + + // Conditionals + new IfThenElseKeywordParser('if', 'then', 'else'), + new AnyOfKeywordParser('anyOf'), + new AllOfKeywordParser('allOf'), + new OneOfKeywordParser('oneOf'), + new NotKeywordParser('not'), + + // Unevaluated + new UnevaluatedPropertiesKeywordParser('unevaluatedProperties'), + new UnevaluatedItemsKeywordParser('unevaluatedItems'), + + // Optional + new DefaultKeywordParser('default'), + ]; + } + +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/KeywordParser.php b/vendor/opis/json-schema/src/Parsers/KeywordParser.php new file mode 100644 index 0000000..4a49a24 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/KeywordParser.php @@ -0,0 +1,62 @@ +draft(); + return $draft !== '06' && $draft !== '07'; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/KeywordParserTrait.php b/vendor/opis/json-schema/src/Parsers/KeywordParserTrait.php new file mode 100644 index 0000000..b604afc --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/KeywordParserTrait.php @@ -0,0 +1,76 @@ +keyword = $keyword; + } + + /** + * @param object|SchemaInfo $schema + * @param string|null $keyword + * @return bool + */ + protected function keywordExists(object $schema, ?string $keyword = null): bool + { + if ($schema instanceof SchemaInfo) { + $schema = $schema->data(); + } + + return property_exists($schema, $keyword ?? $this->keyword); + } + + /** + * @param object|SchemaInfo $schema + * @param string|null $keyword + * @return mixed + */ + protected function keywordValue(object $schema, ?string $keyword = null) + { + if ($schema instanceof SchemaInfo) { + $schema = $schema->data(); + } + + return $schema->{$keyword ?? $this->keyword}; + } + + /** + * @param string $message + * @param SchemaInfo $info + * @param string|null $keyword + * @return InvalidKeywordException + */ + protected function keywordException(string $message, SchemaInfo $info, ?string $keyword = null): InvalidKeywordException + { + $keyword = $keyword ?? $this->keyword; + + return new InvalidKeywordException(str_replace('{keyword}', $keyword, $message), $keyword, $info); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/KeywordValidatorParser.php b/vendor/opis/json-schema/src/Parsers/KeywordValidatorParser.php new file mode 100644 index 0000000..19e4324 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/KeywordValidatorParser.php @@ -0,0 +1,34 @@ +option('allowPragmas') || !$this->keywordExists($info)) { + return null; + } + + $value = $this->keywordValue($info); + + if (!is_object($value)) { + throw $this->keywordException('{keyword} must be an object', $info); + } + + $list = []; + + $draft = $info->draft() ?? $parser->defaultDraftVersion(); + + $pragmaInfo = new SchemaInfo($value, null, $info->id() ?? $info->base(), $info->root(), + array_merge($info->path(), [$this->keyword]), $draft); + + foreach ($parser->draft($draft)->pragmas() as $pragma) { + if ($handler = $pragma->parse($pragmaInfo, $parser, $shared)) { + $list[] = $handler; + } + } + + return $list ? new PragmaKeywordValidator($list) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/AdditionalItemsKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/AdditionalItemsKeywordParser.php new file mode 100644 index 0000000..ceb0c82 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/AdditionalItemsKeywordParser.php @@ -0,0 +1,63 @@ +option('keepAdditionalItemsKeyword') && $info->draft() === '2020-12') { + return null; + } + + $schema = $info->data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + if (!property_exists($schema, 'items') || !is_array($schema->items)) { + // Ignore additionalItems + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_bool($value) && !is_object($value)) { + throw $this->keywordException("{keyword} must be a json schema (object or boolean)", $info); + } + + return new AdditionalItemsKeyword($value, count($schema->items)); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/AdditionalPropertiesKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/AdditionalPropertiesKeywordParser.php new file mode 100644 index 0000000..931cd3f --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/AdditionalPropertiesKeywordParser.php @@ -0,0 +1,54 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_bool($value) && !is_object($value)) { + throw $this->keywordException("{keyword} must be a json schema (object or boolean)", $info); + } + + return new AdditionalPropertiesKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/AllOfKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/AllOfKeywordParser.php new file mode 100644 index 0000000..8831826 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/AllOfKeywordParser.php @@ -0,0 +1,75 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_array($value)) { + throw $this->keywordException("{keyword} should be an array of json schemas", $info); + } + + if (!$value) { + throw $this->keywordException("{keyword} must have at least one element", $info); + } + + $valid = 0; + + foreach ($value as $index => $item) { + if ($item === false) { + throw $this->keywordException("{keyword} contains false schema", $info); + } + if ($item === true) { + $valid++; + continue; + } + if (!is_object($item)) { + throw $this->keywordException("{keyword}[{$index}] must be a json schema", $info); + } elseif (!count(get_object_vars($item))) { + $valid++; + } + } + + return $valid !== count($value) ? new AllOfKeyword($value) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/AnyOfKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/AnyOfKeywordParser.php new file mode 100644 index 0000000..5dd76a4 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/AnyOfKeywordParser.php @@ -0,0 +1,75 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_array($value)) { + throw $this->keywordException("{keyword} should be an array of json schemas", $info); + } + + if (!$value) { + throw $this->keywordException("{keyword} must have at least one element", $info); + } + + $alwaysValid = false; + + foreach ($value as $index => $item) { + if ($item === true) { + $alwaysValid = true; + continue; + } + if ($item === false) { + continue; + } + if (!is_object($item)) { + throw $this->keywordException("{keyword}[{$index}] must be a json schema", $info); + } elseif (!count(get_object_vars($item))) { + $alwaysValid = true; + } + } + + return new AnyOfKeyword($value, $alwaysValid); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/ConstKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/ConstKeywordParser.php new file mode 100644 index 0000000..f15cd15 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/ConstKeywordParser.php @@ -0,0 +1,74 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new ConstDataKeyword($pointer); + } + } + + $type = Helper::getJsonType($value); + if ($type === null) { + throw $this->keywordException("{keyword} contains unknown json data type", $info); + } + + if (isset($shared->types)) { + if (!Helper::jsonTypeMatches($type, $shared->types)) { + throw $this->keywordException("{keyword} contains a value that doesn't match the type keyword", $info); + } + } else { + $shared->types = [$type]; + } + + return new ConstKeyword($value); + } + +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/ContainsKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/ContainsKeywordParser.php new file mode 100644 index 0000000..e6e1c2d --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/ContainsKeywordParser.php @@ -0,0 +1,85 @@ +minContains = $minContains; + $this->maxContains = $maxContains; + } + + /** + * @inheritDoc + */ + public function type(): string + { + return self::TYPE_ARRAY; + } + + /** + * @inheritDoc + */ + public function parse(SchemaInfo $info, SchemaParser $parser, object $shared): ?Keyword + { + $schema = $info->data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_bool($value) && !is_object($value)) { + throw $this->keywordException("{keyword} must be a json schema (object or boolean)", $info); + } + + $min = $max = null; + + if ($this->minContains && $this->keywordExists($schema, $this->minContains)) { + $min = $this->keywordValue($schema, $this->minContains); + if (!is_int($min) || $min < 0) { + throw $this->keywordException("{keyword} must be a non-negative integer", $info, $this->minContains); + } + } + + if ($this->maxContains && $this->keywordExists($schema, $this->maxContains)) { + $max = $this->keywordValue($schema, $this->maxContains); + if (!is_int($max) || $max < 0) { + throw $this->keywordException("{keyword} must be a non-negative integer", $info, $this->maxContains); + } + if ($min !== null && $max < $min) { + throw $this->keywordException("{keyword} must be greater than {$this->minContains}", $info, $this->maxContains); + } + } elseif ($min === 0) { + return null; + } + + return new ContainsKeyword($value, $min, $max); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/ContentEncodingKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/ContentEncodingKeywordParser.php new file mode 100644 index 0000000..992019b --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/ContentEncodingKeywordParser.php @@ -0,0 +1,62 @@ +optionAllowedForDraft('decodeContent', $info, $parser)) { + return null; + } + + $schema = $info->data(); + + $resolver = $parser->getContentEncodingResolver(); + + if (!$resolver || !$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_string($value)) { + throw $this->keywordException("{keyword} must be a string", $info); + } + + return new ContentEncodingKeyword(strtolower($value), $resolver); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/ContentMediaTypeKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/ContentMediaTypeKeywordParser.php new file mode 100644 index 0000000..97c5cac --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/ContentMediaTypeKeywordParser.php @@ -0,0 +1,62 @@ +optionAllowedForDraft('decodeContent', $info, $parser)) { + return null; + } + + $schema = $info->data(); + + $resolver = $parser->getMediaTypeResolver(); + + if (!$resolver || !$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_string($value)) { + throw $this->keywordException("{keyword} must be a string", $info); + } + + return new ContentMediaTypeKeyword($value, $resolver); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/ContentSchemaKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/ContentSchemaKeywordParser.php new file mode 100644 index 0000000..58cce2f --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/ContentSchemaKeywordParser.php @@ -0,0 +1,60 @@ +optionAllowedForDraft('decodeContent', $info, $parser)) { + return null; + } + + $schema = $info->data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_object($value)) { + throw $this->keywordException("{keyword} must be a valid json schema object", $info); + } + + return new ContentSchemaKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/DefaultKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/DefaultKeywordParser.php new file mode 100644 index 0000000..bf13a6f --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/DefaultKeywordParser.php @@ -0,0 +1,85 @@ +properties = $properties; + } + + /** + * @inheritDoc + */ + public function type(): string + { + return self::TYPE_APPEND; + } + + /** + * @inheritDoc + */ + public function parse(SchemaInfo $info, SchemaParser $parser, object $shared): ?Keyword + { + $schema = $info->data(); + + if (!$parser->option('allowDefaults')) { + return null; + } + + $defaults = null; + + if ($this->keywordExists($schema)) { + $defaults = $this->keywordValue($schema); + + if (is_object($defaults)) { + $defaults = (array)Helper::cloneValue($defaults); + } else { + $defaults = null; + } + } + + if ($this->properties !== null && property_exists($schema, $this->properties) + && is_object($schema->{$this->properties})) { + foreach ($schema->{$this->properties} as $name => $value) { + if (is_object($value) && property_exists($value, $this->keyword)) { + $defaults[$name] = $value->{$this->keyword}; + } + } + } + + if (!$defaults) { + return null; + } + + return new DefaultKeyword($defaults); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/DependenciesKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/DependenciesKeywordParser.php new file mode 100644 index 0000000..078a3b9 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/DependenciesKeywordParser.php @@ -0,0 +1,80 @@ +option('keepDependenciesKeyword') && !in_array($info->draft(), ['06', '07'])) { + return null; + } + + $schema = $info->data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + if (!is_object($value)) { + throw $this->keywordException("{keyword} must be an object", $info); + } + + $list = get_object_vars($value); + + foreach ($list as $name => $s) { + if (is_array($s)) { + if (!$s) { + unset($list[$name]); + continue; + } + foreach ($s as $p) { + if (!is_string($p)) { + throw $this->keywordException("{keyword} must be an object containing json schemas or arrays of property names", $info); + } + } + $list[$name] = array_unique($s); + } elseif (is_bool($s)) { + if ($s) { + unset($list[$name]); + } + } elseif (!is_object($s)) { + throw $this->keywordException("{keyword} must be an object containing json schemas or arrays of property names", $info); + } + } + + return $list ? new DependenciesKeyword($list) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/DependentRequiredKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/DependentRequiredKeywordParser.php new file mode 100644 index 0000000..d8f4289 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/DependentRequiredKeywordParser.php @@ -0,0 +1,70 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + if (!is_object($value)) { + throw $this->keywordException("{keyword} must be an object", $info); + } + + $list = []; + foreach ($value as $name => $s) { + if (!is_array($s)) { + throw $this->keywordException("{keyword} must be an object containing json schemas or arrays of property names", $info); + } + if (!$s) { + // Empty array + continue; + } + foreach ($s as $p) { + if (!is_string($p)) { + throw $this->keywordException("{keyword} must be an object containing arrays of property names", $info); + } + } + $list[$name] = array_unique($s); + } + + return $list ? new DependentRequiredKeyword($list) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/DependentSchemasKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/DependentSchemasKeywordParser.php new file mode 100644 index 0000000..4fa313a --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/DependentSchemasKeywordParser.php @@ -0,0 +1,73 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + if (!is_object($value)) { + throw $this->keywordException("{keyword} must be an object", $info); + } + + $valid = 0; + $total = 0; + + foreach ($value as $name => $s) { + $total++; + if (is_bool($s)) { + if ($s) { + $valid++; + } + } elseif (!is_object($s)) { + throw $this->keywordException("{keyword} must be an object containing json schemas", $info); + } elseif (!count(get_object_vars($s))) { + $valid++; + } + } + + if (!$total) { + return null; + } + + return $valid !== $total ? new DependentSchemasKeyword($value) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/EnumKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/EnumKeywordParser.php new file mode 100644 index 0000000..e666c9e --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/EnumKeywordParser.php @@ -0,0 +1,107 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new EnumDataKeyword($pointer); + } + } + + if (!is_array($value) || !$value) { + throw $this->keywordException("{keyword} must be a non-empty array", $info); + } + + $hasConst = property_exists($schema, 'const'); + $constMatched = false; + + $allowedTypes = isset($shared->types) ? $shared->types : null; + $foundTypes = []; + $list = []; + foreach ($value as $item) { + $type = Helper::getJsonType($item); + if ($type === null) { + throw $this->keywordException("{keyword} contains invalid json data type", $info); + } + + if ($allowedTypes && !Helper::jsonTypeMatches($type, $allowedTypes)) { + continue; + } + + if ($hasConst && Helper::equals($item, $schema->const)) { + $constMatched = true; + break; + } + + if (!in_array($type, $foundTypes)) { + $foundTypes[] = $type; + } + + $list[] = $item; + } + + if ($hasConst) { + if ($constMatched) { + return null; + } + throw $this->keywordException("{keyword} does not contain the value of const keyword", $info); + } + + if ($foundTypes) { + if ($allowedTypes === null) { + $shared->types = $foundTypes; + } else { + $shared->types = array_unique(array_merge($shared->types, $foundTypes)); + } + } + + return new EnumKeyword($list); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/ExclusiveMaximumKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/ExclusiveMaximumKeywordParser.php new file mode 100644 index 0000000..afe8f78 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/ExclusiveMaximumKeywordParser.php @@ -0,0 +1,70 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (is_bool($value) && $parser->option('allowExclusiveMinMaxAsBool')) { + return null; + } + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new ExclusiveMaximumDataKeyword($pointer); + } + } + + if (!is_int($value) && !is_float($value) || is_nan($value) || !is_finite($value)) { + throw $this->keywordException('{keyword} must contain a valid number', $info); + } + + return new ExclusiveMaximumKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/ExclusiveMinimumKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/ExclusiveMinimumKeywordParser.php new file mode 100644 index 0000000..540d62d --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/ExclusiveMinimumKeywordParser.php @@ -0,0 +1,70 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (is_bool($value) && $parser->option('allowExclusiveMinMaxAsBool')) { + return null; + } + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new ExclusiveMinimumDataKeyword($pointer); + } + } + + if (!is_int($value) && !is_float($value) || is_nan($value) || !is_finite($value)) { + throw $this->keywordException('{keyword} must contain a valid number', $info); + } + + return new ExclusiveMinimumKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/FiltersKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/FiltersKeywordParser.php new file mode 100644 index 0000000..29ab8f4 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/FiltersKeywordParser.php @@ -0,0 +1,161 @@ +data(); + + if (!$parser->option('allowFilters')) { + return null; + } + + $resolver = $parser->getFilterResolver(); + + if (!$resolver || !$this->keywordExists($schema)) { + return null; + } + + $filters = $this->parseFilters($parser, $resolver, $this->keywordValue($schema), $info); + if (!$filters) { + return null; + } + + return new FiltersKeyword($filters); + } + + /** + * @param SchemaParser $parser + * @param FilterResolver $filterResolver + * @param mixed $filters + * @param SchemaInfo $info + * @return array|null + */ + protected function parseFilters( + SchemaParser $parser, + FilterResolver $filterResolver, + $filters, + SchemaInfo $info + ): ?array + { + if (is_string($filters)) { + if ($filters = $this->parseFilter($parser, $filterResolver, $filters, $info)) { + return [$filters]; + } + + return null; + } + + if (is_object($filters)) { + if ($filter = $this->parseFilter($parser, $filterResolver, $filters, $info)) { + return [$filter]; + } + + return null; + } + + if (is_array($filters)) { + if (!$filters) { + return null; + } + $list = []; + foreach ($filters as $filter) { + if ($filter = $this->parseFilter($parser, $filterResolver, $filter, $info)) { + $list[] = $filter; + } + } + + return $list ?: null; + } + + throw $this->keywordException('{keyword} can be a non-empty string, an object or an array of string and objects', $info); + } + + /** + * @param SchemaParser $parser + * @param FilterResolver $resolver + * @param $filter + * @param SchemaInfo $info + * @return object|null + */ + protected function parseFilter( + SchemaParser $parser, + FilterResolver $resolver, + $filter, + SchemaInfo $info + ): ?object + { + $vars = null; + if (is_object($filter)) { + if (!property_exists($filter, '$func') || !is_string($filter->{'$func'}) || $filter->{'$func'} === '') { + throw $this->keywordException('$func (for {keyword}) must be a non-empty string', $info); + } + + $vars = get_object_vars($filter); + unset($vars['$func']); + + if (property_exists($filter, '$vars')) { + if (!is_object($filter->{'$vars'})) { + throw $this->keywordException('$vars (for {keyword}) must be a string', $info); + } + unset($vars['$vars']); + $vars = get_object_vars($filter->{'$vars'}) + $vars; + } + + $filter = $filter->{'$func'}; + } elseif (!is_string($filter) || $filter === '') { + throw $this->keywordException('{keyword} can be a non-empty string, an object or an array of string and objects', $info); + } + + $list = $resolver->resolveAll($filter); + if (!$list) { + throw $this->keywordException("{keyword}: {$filter} doesn't exists", $info); + } + + $list = $this->resolveSubTypes($list); + + return (object)[ + 'name' => $filter, + 'args' => $vars ? $this->createVariables($parser, $vars) : null, + 'types' => $list, + ]; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/FormatKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/FormatKeywordParser.php new file mode 100644 index 0000000..b3c0262 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/FormatKeywordParser.php @@ -0,0 +1,71 @@ +data(); + + $resolver = $parser->getFormatResolver(); + + if (!$resolver || !$parser->option('allowFormats') || !$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new FormatDataKeyword($pointer, $resolver); + } + } + + if (!is_string($value)) { + throw $this->keywordException("{keyword} must be a string", $info); + } + + $list = $resolver->resolveAll($value); + + if (!$list) { + return null; + } + + return new FormatKeyword($value, $this->resolveSubTypes($list)); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/IfThenElseKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/IfThenElseKeywordParser.php new file mode 100644 index 0000000..7ba5001 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/IfThenElseKeywordParser.php @@ -0,0 +1,109 @@ +then = $then; + $this->else = $else; + } + + /** + * @inheritDoc + */ + public function type(): string + { + return self::TYPE_AFTER; + } + + /** + * @inheritDoc + */ + public function parse(SchemaInfo $info, SchemaParser $parser, object $shared): ?Keyword + { + $schema = $info->data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $if = $this->keywordValue($schema); + if (!$this->isJsonSchema($if)) { + throw $this->keywordException("{keyword} keyword must be a json schema", $info); + } + + $then = true; + if (property_exists($schema, $this->then)) { + $then = $schema->{$this->then}; + } + if (!$this->isJsonSchema($then)) { + throw $this->keywordException("{keyword} keyword must be a json schema", $info, $this->then); + } + + $else = true; + if (property_exists($schema, $this->else)) { + $else = $schema->{$this->else}; + } + if (!$this->isJsonSchema($else)) { + throw $this->keywordException("{keyword} keyword must be a json schema", $info, $this->else); + } + + if ($if === true) { + if ($then === true) { + return null; + } + $else = true; + } elseif ($if === false) { + if ($else === true) { + return null; + } + $then = true; + } elseif ($then === true && $else === true) { + return null; + } + + return new IfThenElseKeyword($if, $then, $else); + } + + /** + * @param $value + * @return bool + */ + protected function isJsonSchema($value): bool + { + return is_bool($value) || is_object($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/ItemsKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/ItemsKeywordParser.php new file mode 100644 index 0000000..697ec60 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/ItemsKeywordParser.php @@ -0,0 +1,117 @@ +mode = $mode; + $this->startIndexKeyword = $startIndexKeyword; + } + + /** + * @inheritDoc + */ + public function type(): string + { + return self::TYPE_ARRAY; + } + + /** + * @inheritDoc + */ + public function parse(SchemaInfo $info, SchemaParser $parser, object $shared): ?Keyword + { + $schema = $info->data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + $alwaysValid = false; + + if (is_bool($value)) { + if ($this->mode === self::ONLY_ARRAY) { + throw $this->keywordException("{keyword} must contain an array of json schemas", $info); + } + if ($value) { + $alwaysValid = true; + } + } elseif (is_array($value)) { + if ($this->mode === self::ONLY_SCHEMA) { + throw $this->keywordException("{keyword} must contain a valid json schema", $info); + } + $valid = 0; + foreach ($value as $index => $v) { + if (is_bool($v)) { + if ($v) { + $valid++; + } + } elseif (!is_object($v)) { + throw $this->keywordException("{keyword}[$index] must contain a valid json schema", $info); + } elseif (!count(get_object_vars($v))) { + $valid++; + } + } + if ($valid === count($value)) { + $alwaysValid = true; + } + } elseif (!is_object($value)) { + if ($this->mode === self::BOTH) { + throw $this->keywordException("{keyword} must be a json schema or an array of json schemas", $info); + } elseif ($this->mode === self::ONLY_ARRAY) { + throw $this->keywordException("{keyword} must contain an array of json schemas", $info); + } else { + throw $this->keywordException("{keyword} must contain a valid json schema", $info); + } + } else { + if ($this->mode === self::ONLY_ARRAY) { + throw $this->keywordException("{keyword} must contain an array of json schemas", $info); + } + if (!count(get_object_vars($value))) { + $alwaysValid = true; + } + } + + $startIndex = 0; + if ($this->startIndexKeyword !== null && $this->keywordExists($schema, $this->startIndexKeyword)) { + $start = $this->keywordValue($schema, $this->startIndexKeyword); + if (is_array($start)) { + $startIndex = count($start); + } + } + + return new ItemsKeyword($value, $alwaysValid, $this->keyword, $startIndex); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MaxItemsKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MaxItemsKeywordParser.php new file mode 100644 index 0000000..e24fa75 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MaxItemsKeywordParser.php @@ -0,0 +1,63 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new MaxItemsDataKeyword($pointer); + } + } + + if (!is_int($value) || $value < 0) { + throw $this->keywordException("{keyword} most be a positive integer", $info); + } + + return new MaxItemsKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MaxLengthKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MaxLengthKeywordParser.php new file mode 100644 index 0000000..54bc88b --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MaxLengthKeywordParser.php @@ -0,0 +1,63 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new MaxLengthDataKeyword($pointer); + } + } + + if (!is_int($value) || $value < 0) { + throw $this->keywordException("{keyword} must be a non-negative integer", $info); + } + + return new MaxLengthKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MaxPropertiesKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MaxPropertiesKeywordParser.php new file mode 100644 index 0000000..971d3c8 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MaxPropertiesKeywordParser.php @@ -0,0 +1,63 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new MaxPropertiesDataKeyword($pointer); + } + } + + if (!is_int($value) || $value < 0) { + throw $this->keywordException("{keyword} must be a non-negative integer", $info); + } + + return new MaxPropertiesKeywords($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MaximumKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MaximumKeywordParser.php new file mode 100644 index 0000000..1eb9824 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MaximumKeywordParser.php @@ -0,0 +1,91 @@ +exclusiveKeyword = $exclusiveKeyword; + } + + /** + * @inheritDoc + */ + public function type(): string + { + return self::TYPE_NUMBER; + } + + /** + * @inheritDoc + */ + public function parse(SchemaInfo $info, SchemaParser $parser, object $shared): ?Keyword + { + $schema = $info->data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + $exclusive = false; + if ($parser->option('allowExclusiveMinMaxAsBool') && + $this->exclusiveKeyword !== null && + property_exists($schema, $this->exclusiveKeyword)) { + $exclusive = $schema->{$this->exclusiveKeyword} === true; + } + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return $exclusive + ? new ExclusiveMaximumDataKeyword($pointer) + : new MaximumDataKeyword($pointer); + } + } + + if (!is_int($value) && !is_float($value) || is_nan($value) || !is_finite($value)) { + throw $this->keywordException('{keyword} must contain a valid number', $info); + } + + return $exclusive + ? new ExclusiveMaximumKeyword($value) + : new MaximumKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MinItemsKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MinItemsKeywordParser.php new file mode 100644 index 0000000..55b40aa --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MinItemsKeywordParser.php @@ -0,0 +1,67 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new MinItemsDataKeyword($pointer); + } + } + + if (!is_int($value) || $value < 0) { + throw $this->keywordException("{keyword} most be a positive integer", $info); + } + + if ($value === 0) { + return null; + } + + return new MinItemsKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MinLengthKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MinLengthKeywordParser.php new file mode 100644 index 0000000..0a4ab4e --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MinLengthKeywordParser.php @@ -0,0 +1,67 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new MinLengthDataKeyword($pointer); + } + } + + if (!is_int($value) || $value < 0) { + throw $this->keywordException("{keyword} must be a non-negative integer", $info); + } + + if ($value === 0) { + return null; + } + + return new MinLengthKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MinPropertiesKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MinPropertiesKeywordParser.php new file mode 100644 index 0000000..c8f8928 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MinPropertiesKeywordParser.php @@ -0,0 +1,67 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new MinPropertiesDataKeyword($pointer); + } + } + + if (!is_int($value) || $value < 0) { + throw $this->keywordException("{keyword} must be a non-negative integer", $info); + } + + if ($value === 0) { + return null; + } + + return new MinPropertiesKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MinimumKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MinimumKeywordParser.php new file mode 100644 index 0000000..640ca90 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MinimumKeywordParser.php @@ -0,0 +1,91 @@ +exclusiveKeyword = $exclusiveKeyword; + } + + /** + * @inheritDoc + */ + public function type(): string + { + return self::TYPE_NUMBER; + } + + /** + * @inheritDoc + */ + public function parse(SchemaInfo $info, SchemaParser $parser, object $shared): ?Keyword + { + $schema = $info->data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + $exclusive = false; + if ($parser->option('allowExclusiveMinMaxAsBool') && + $this->exclusiveKeyword !== null && + property_exists($schema, $this->exclusiveKeyword)) { + $exclusive = $schema->{$this->exclusiveKeyword} === true; + } + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return $exclusive + ? new ExclusiveMinimumDataKeyword($pointer) + : new MinimumDataKeyword($pointer); + } + } + + if (!is_int($value) && !is_float($value) || is_nan($value) || !is_finite($value)) { + throw $this->keywordException('{keyword} must contain a valid number', $info); + } + + return $exclusive + ? new ExclusiveMinimumKeyword($value) + : new MinimumKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/MultipleOfKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/MultipleOfKeywordParser.php new file mode 100644 index 0000000..8281d47 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/MultipleOfKeywordParser.php @@ -0,0 +1,67 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new MultipleOfDataKeyword($pointer); + } + } + + if (!is_int($value) && !is_float($value) || is_nan($value) || !is_finite($value)) { + throw $this->keywordException("{keyword} must be a valid number (integer or float)", $info); + } + + if ($value <= 0) { + throw $this->keywordException("{keyword} must be greater than zero", $info); + } + + return new MultipleOfKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/NotKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/NotKeywordParser.php new file mode 100644 index 0000000..53bc577 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/NotKeywordParser.php @@ -0,0 +1,58 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (is_bool($value)) { + if (!$value) { + return null; + } + } elseif (!is_object($value)) { + throw $this->keywordException("{keyword} must contain a json schema (object or boolean)", $info); + } + + return new NotKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/OneOfKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/OneOfKeywordParser.php new file mode 100644 index 0000000..66e0693 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/OneOfKeywordParser.php @@ -0,0 +1,79 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_array($value)) { + throw $this->keywordException("{keyword} should be an array of json schemas", $info); + } + + if (!$value) { + throw $this->keywordException("{keyword} must have at least one element", $info); + } + + $valid = 0; + + foreach ($value as $index => $item) { + if ($item === false) { + continue; + } + if ($item === true) { + if (++$valid > 1) { + throw $this->keywordException("{keyword} contains multiple true values", $info); + } + continue; + } + if (!is_object($item)) { + throw $this->keywordException("{keyword}[{$index}] must be a json schema", $info); + } elseif (!count(get_object_vars($item))) { + if (++$valid > 1) { + throw $this->keywordException("{keyword} contains multiple true values", $info); + } + } + } + + return new OneOfKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/PatternKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/PatternKeywordParser.php new file mode 100644 index 0000000..bae5466 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/PatternKeywordParser.php @@ -0,0 +1,67 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new PatternDataKeyword($pointer); + } + } + + if (!is_string($value)) { + throw $this->keywordException("{keyword} value must be a string", $info); + } + + if (!Helper::isValidPattern($value)) { + throw $this->keywordException("{keyword} value must be a valid regex", $info); + } + + return new PatternKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/PatternPropertiesKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/PatternPropertiesKeywordParser.php new file mode 100644 index 0000000..70f1085 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/PatternPropertiesKeywordParser.php @@ -0,0 +1,67 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + if (!is_object($value)) { + throw $this->keywordException("{keyword} must be an object", $info); + } + + $list = []; + + foreach ($value as $pattern => $item) { + if (!Helper::isValidPattern($pattern)) { + throw $this->keywordException("Each property name from {keyword} must be valid regex", $info); + } + + if (!is_bool($item) && !is_object($item)) { + throw $this->keywordException("{keyword}[{$pattern}] must be a json schema (object or boolean)", $info); + } + + $list[$pattern] = $item; + } + + return $list ? new PatternPropertiesKeyword($list) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/PropertiesKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/PropertiesKeywordParser.php new file mode 100644 index 0000000..9bdf76b --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/PropertiesKeywordParser.php @@ -0,0 +1,64 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_object($value)) { + throw $this->keywordException("{keyword} must be an object", $info); + } + + $list = []; + + foreach ($value as $name => $s) { + if (!is_bool($s) && !is_object($s)) { + throw $this->keywordException("{keyword}[{$name}] must be a json schema (object or boolean)", $info); + } + + $list[$name] = $s; + } + + return $list ? new PropertiesKeyword($list) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/PropertyNamesKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/PropertyNamesKeywordParser.php new file mode 100644 index 0000000..d8f3b2d --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/PropertyNamesKeywordParser.php @@ -0,0 +1,58 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (is_bool($value)) { + if ($value) { + return null; + } + } elseif (!is_object($value)) { + throw $this->keywordException("{keyword} must be a valid json schema (object or boolean)", $info); + } + + return new PropertyNamesKeyword($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/RefKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/RefKeywordParser.php new file mode 100644 index 0000000..5c14856 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/RefKeywordParser.php @@ -0,0 +1,228 @@ +variations = $variations; + } + + /** + * @inheritDoc + */ + public function type(): string + { + return self::TYPE_AFTER_REF; + } + + /** + * @inheritDoc + */ + public function parse(SchemaInfo $info, SchemaParser $parser, object $shared): ?Keyword + { + $ref = null; + $recursive = false; + $schema = $info->data(); + $variation = null; + + if ($this->keywordExists($schema)) { + $ref = $this->keywordValue($schema); + if (!is_string($ref) || $ref === '') { + throw $this->keywordException('{keyword} must be a non-empty string', $info); + } + } elseif ($this->variations) { + foreach ($this->variations as $v) { + if (!$this->keywordExists($schema, $v['ref'])) { + continue; + } + $ref = $this->keywordValue($schema, $v['ref']); + if ($v['fragment']) { + if (!preg_match('/^#[a-z][a-z0-9\\-.:_]*/i', $ref)) { + $this->keywordException("{keyword} value is malformed", $info, $v['ref']); + } + } elseif ($ref !== '#') { + $this->keywordException("{keyword} supports only '#' as value", $info, $v['ref']); + } + $variation = $v; + $recursive = true; + break; + } + if (!$recursive) { + return null; + } + } else { + return null; + } + + // Mappers + $mapper = null; + if ($parser->option('allowMappers') && property_exists($schema, '$map')) { + if (!is_object($schema->{'$map'}) && !is_array($schema->{'$map'})) { + throw $this->keywordException('$map keyword must be an object or an array', $info, '$map'); + } + + if (!empty($schema->{'$map'})) { + $mapper = $this->createVariables($parser, $schema->{'$map'}); + } + } + + // Globals + $globals = null; + if ($parser->option('allowGlobals') && property_exists($schema, '$globals')) { + if (!is_object($schema->{'$globals'})) { + throw $this->keywordException('$globals keyword must be an object', $info, '$globals'); + } + + if (!empty($schema->{'$globals'})) { + $globals = $this->createVariables($parser, $schema->{'$globals'}); + } + } + + // Pass slots + $slots = null; + if ($parser->option('allowSlots') && property_exists($schema, '$inject')) { + $slots = $this->parseInjectedSlots($info, $parser, '$inject'); + } + + if ($recursive) { + $ref = $info->idBaseRoot()->resolveRef($ref); + if ($variation['fragment']) { + return new RecursiveRefKeyword($ref->resolveRef('#'), $mapper, $globals, $slots, + $variation['ref'], $variation['anchor'], $ref->fragment()); + } + return new RecursiveRefKeyword($ref, $mapper, $globals, $slots, + $variation['ref'], $variation['anchor'], true); + } + + if ($ref === '#') { + return new URIRefKeyword(Uri::merge('#', $info->idBaseRoot()), $mapper, $globals, $slots, $this->keyword); + } + + if ($parser->option('allowTemplates') && UriTemplate::isTemplate($ref)) { + $tpl = new UriTemplate($ref); + + if ($tpl->hasPlaceholders()) { + $vars = null; + + if (property_exists($schema, '$vars')) { + if (!is_object($schema->{'$vars'})) { + throw $this->keywordException('$vars keyword must be an object', $info, '$vars'); + } + + if (!empty($schema->{'$vars'})) { + $vars = $this->createVariables($parser, $schema->{'$vars'}); + } + } + + return new TemplateRefKeyword( + $tpl, $vars, $mapper, + $globals, $slots, $this->keyword, + $parser->option('allowRelativeJsonPointerInRef') + ); + } + + unset($tpl); + } + + if ($ref[0] === '#') { + if (($pointer = JsonPointer::parse(substr($ref, 1))) && $pointer->isAbsolute()) { + return new PointerRefKeyword($pointer, $mapper, $globals, $slots, $this->keyword); + } + } elseif ($parser->option('allowRelativeJsonPointerInRef') && + ($pointer = JsonPointer::parse($ref)) && $pointer->isRelative()) { + return new PointerRefKeyword($pointer, $mapper, $globals, $slots, $this->keyword); + } + + $ref = Uri::merge($ref, $info->idBaseRoot(), true); + + if ($ref === null || !$ref->isAbsolute()) { + throw $this->keywordException('{keyword} must be a valid uri, uri-reference, uri-template or json-pointer', + $info); + } + + return new URIRefKeyword($ref, $mapper, $globals, $slots, $this->keyword); + } + + /** + * @param SchemaInfo $info + * @param SchemaParser $parser + * @param string $keyword + * @return string[]|object[]|Schema[] + */ + protected function parseInjectedSlots(SchemaInfo $info, SchemaParser $parser, string $keyword): ?array + { + $schema = $info->data(); + + if (!is_object($schema->{$keyword})) { + throw $this->keywordException('{keyword} keyword value must be an object', $info, $keyword); + } + + return $this->getSlotSchemas($info, $parser, $schema->{$keyword}, [$keyword]); + } + + /** + * @param SchemaInfo $info + * @param SchemaParser $parser + * @param object $slots + * @param array $path + * @return null + */ + protected function getSlotSchemas(SchemaInfo $info, SchemaParser $parser, object $slots, array $path): ?array + { + $keyword = null; + if ($path) { + $keyword = end($path); + $path = array_merge($info->path(), $path); + } else { + $path = $info->path(); + } + + $list = []; + + foreach ($slots as $name => $value) { + if ($value === null) { + continue; + } + if (is_string($value) || is_object($value)) { + $list[$name] = $value; + } elseif (is_bool($value)) { + $list[$name] = $parser->parseSchema(new SchemaInfo( + $value, null, $info->id() ?? $info->base(), $info->root(), + array_merge($path, [$name]), + $info->draft() ?? $parser->defaultDraftVersion() + )); + } else { + throw $this->keywordException('Slots must contain valid json schemas or slot names', $info, $keyword); + } + } + + return $list ?: null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/RequiredKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/RequiredKeywordParser.php new file mode 100644 index 0000000..b66557e --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/RequiredKeywordParser.php @@ -0,0 +1,105 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + $filter = $this->propertiesFilter($parser, $schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new RequiredDataKeyword($pointer, $filter); + } + } + + if (!is_array($value)) { + throw $this->keywordException("{keyword} must be an array of strings", $info); + } + + foreach ($value as $name) { + if (!is_string($name)) { + throw $this->keywordException("{keyword} must be an array of strings", $info); + } + } + + if ($filter) { + $value = array_filter($value, $filter); + } + + return $value ? new RequiredKeyword(array_unique($value)) : null; + } + + /** + * @param SchemaParser $parser + * @param object $schema + * @return callable|null + */ + protected function propertiesFilter(SchemaParser $parser, object $schema): ?callable + { + if (!$parser->option('allowDefaults')) { + return null; + } + + if (!property_exists($schema, 'properties') || !is_object($schema->properties)) { + return null; + } + + $props = $schema->properties; + + return static function (string $name) use ($props) { + if (!property_exists($props, $name)) { + return true; + } + + if (is_object($props->{$name}) && property_exists($props->{$name}, 'default')) { + return false; + } + + return true; + }; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/SlotsKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/SlotsKeywordParser.php new file mode 100644 index 0000000..176de51 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/SlotsKeywordParser.php @@ -0,0 +1,64 @@ +data(); + + if (!$parser->option('allowSlots') || !$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if (!is_object($value)) { + throw $this->keywordException('{keyword} keyword value must be an object', $info); + } + + $slots = []; + foreach ($value as $name => $fallback) { + if (!is_string($name) || $name === '') { + continue; + } + if (is_bool($fallback) || is_string($fallback) || is_object($fallback)) { + $slots[$name] = $fallback; + } + } + + return $slots ? new SlotsKeyword($slots) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/TypeKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/TypeKeywordParser.php new file mode 100644 index 0000000..764d5c9 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/TypeKeywordParser.php @@ -0,0 +1,78 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $type = $this->keywordValue($schema); + + if (is_string($type)) { + $type = [$type]; + } elseif (!is_array($type)) { + throw $this->keywordException('{keyword} can only be a string or an array of string', $info); + } + + foreach ($type as $t) { + if (!Helper::isValidJsonType($t)) { + throw $this->keywordException("{keyword} contains invalid json type: {$t}", $info); + } + } + + $type = array_unique($type); + + if (!isset($shared->types)) { + $shared->types = $type; + } else { + $shared->types = array_unique(array_merge($shared->types, $type)); + } + + $count = count($type); + + if ($count === 0) { + throw $this->keywordException("{keyword} cannot be an empty array", $info); + } elseif ($count === 1) { + $type = reset($type); + } + + return new TypeKeyword($type); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/UnevaluatedItemsKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/UnevaluatedItemsKeywordParser.php new file mode 100644 index 0000000..b60a029 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/UnevaluatedItemsKeywordParser.php @@ -0,0 +1,73 @@ +data(); + + if (!$this->keywordExists($schema) || !$parser->option('allowUnevaluated')) { + return null; + } + +// if (!$this->makesSense($schema)) { +// return null; +// } + + $value = $this->keywordValue($schema); + + if (!is_bool($value) && !is_object($value)) { + throw $this->keywordException("{keyword} must be a json schema (object or boolean)", $info); + } + + return new UnevaluatedItemsKeyword($value); + } + + protected function makesSense(object $schema): bool + { + if (property_exists($schema, 'additionalItems')) { + return false; + } +// if (property_exists($schema, 'contains')) { +// return false; +// } + if (property_exists($schema, 'items') && !is_array($schema->items)) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/UnevaluatedPropertiesKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/UnevaluatedPropertiesKeywordParser.php new file mode 100644 index 0000000..4e3a22e --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/UnevaluatedPropertiesKeywordParser.php @@ -0,0 +1,68 @@ +data(); + + if (!$this->keywordExists($schema) || !$parser->option('allowUnevaluated')) { + return null; + } + +// if (!$this->makesSense($schema)) { +// return null; +// } + + $value = $this->keywordValue($schema); + + if (!is_bool($value) && !is_object($value)) { + throw $this->keywordException("{keyword} must be a json schema (object or boolean)", $info); + } + + return new UnevaluatedPropertiesKeyword($value); + } + + protected function makesSense(object $schema): bool + { + if (property_exists($schema, 'additionalProperties')) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Keywords/UniqueItemsKeywordParser.php b/vendor/opis/json-schema/src/Parsers/Keywords/UniqueItemsKeywordParser.php new file mode 100644 index 0000000..4712d6b --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Keywords/UniqueItemsKeywordParser.php @@ -0,0 +1,63 @@ +data(); + + if (!$this->keywordExists($schema)) { + return null; + } + + $value = $this->keywordValue($schema); + + if ($this->isDataKeywordAllowed($parser, $this->keyword)) { + if ($pointer = $this->getDataKeywordPointer($value)) { + return new UniqueItemsDataKeyword($pointer); + } + } + + if (!is_bool($value)) { + throw $this->keywordException("{keyword} must be a boolean", $info); + } + + return $value ? new UniqueItemsKeyword() : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/PragmaParser.php b/vendor/opis/json-schema/src/Parsers/PragmaParser.php new file mode 100644 index 0000000..1d20e6a --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/PragmaParser.php @@ -0,0 +1,84 @@ +pragma = $pragma; + } + + /** + * @param SchemaInfo $info + * @param SchemaParser $parser + * @param object $shared + * @return Pragma|null + */ + abstract public function parse(SchemaInfo $info, SchemaParser $parser, object $shared): ?Pragma; + + /** + * @param object|SchemaInfo $schema + * @param string|null $pragma + * @return bool + */ + protected function pragmaExists(object $schema, ?string $pragma = null): bool + { + if ($schema instanceof SchemaInfo) { + $schema = $schema->isObject() ? $schema->data() : null; + } + + return is_object($schema) && property_exists($schema, $pragma ?? $this->pragma); + } + + /** + * @param object|SchemaInfo $schema + * @param string|null $pragma + * @return mixed + */ + protected function pragmaValue(object $schema, ?string $pragma = null) + { + if ($schema instanceof SchemaInfo) { + $schema = $schema->isObject() ? $schema->data() : null; + } + + return is_object($schema) ? $schema->{$pragma ?? $this->pragma} : null; + } + + /** + * @param string $message + * @param SchemaInfo $info + * @param string|null $pragma + * @return InvalidPragmaException + */ + protected function pragmaException(string $message, SchemaInfo $info, ?string $pragma = null): InvalidPragmaException + { + $pragma = $pragma ?? $this->pragma; + + return new InvalidPragmaException(str_replace('{pragma}', $pragma, $message), $pragma, $info); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Pragmas/CastPragmaParser.php b/vendor/opis/json-schema/src/Parsers/Pragmas/CastPragmaParser.php new file mode 100644 index 0000000..e460fef --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Pragmas/CastPragmaParser.php @@ -0,0 +1,45 @@ +pragmaExists($info)) { + return null; + } + + $value = $this->pragmaValue($info); + + if (!is_string($value) || !Helper::isValidJsonType($value)) { + throw $this->pragmaException('Pragma {pragma} must contain a valid json type name', $info); + } + + return new CastPragma($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Pragmas/GlobalsPragmaParser.php b/vendor/opis/json-schema/src/Parsers/Pragmas/GlobalsPragmaParser.php new file mode 100644 index 0000000..55dddb7 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Pragmas/GlobalsPragmaParser.php @@ -0,0 +1,48 @@ +option('allowGlobals') || !$this->pragmaExists($info)) { + return null; + } + + $value = $this->pragmaValue($info); + + if (!is_object($value)) { + throw $this->pragmaException('Pragma {pragma} must be an object', $info); + } + + $value = get_object_vars($value); + + return $value ? new GlobalsPragma($this->createVariables($parser, $value)) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Pragmas/MaxErrorsPragmaParser.php b/vendor/opis/json-schema/src/Parsers/Pragmas/MaxErrorsPragmaParser.php new file mode 100644 index 0000000..168e7d1 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Pragmas/MaxErrorsPragmaParser.php @@ -0,0 +1,44 @@ +pragmaExists($info)) { + return null; + } + + $value = $this->pragmaValue($info); + + if (!is_int($value)) { + throw $this->pragmaException('Pragma {pragma} must be an integer', $info); + } + + return new MaxErrorsPragma($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Pragmas/SlotsPragmaParser.php b/vendor/opis/json-schema/src/Parsers/Pragmas/SlotsPragmaParser.php new file mode 100644 index 0000000..66f5edb --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Pragmas/SlotsPragmaParser.php @@ -0,0 +1,65 @@ +option('allowSlots') || !$this->pragmaExists($info)) { + return null; + } + + $value = $this->pragmaValue($info); + + if (!is_object($value)) { + throw $this->pragmaException('Pragma {pragma} must be an object', $info); + } + + $list = []; + + foreach ($value as $name => $slot) { + if ($slot === null) { + continue; + } + + if (is_bool($slot)) { + + $list[$name] = $parser->parseSchema(new SchemaInfo( + $slot, null, $info->base(), $info->root(), + array_merge($info->path(), [$this->pragma, $name]), + $info->draft() ?? $parser->defaultDraftVersion() + )); + } elseif (is_string($slot) || is_object($slot)) { + $list[$name] = $slot; + } else { + throw $this->pragmaException('Pragma {pragma} contains invalid value for slot ' . $name, $info); + } + } + + return $list ? new SlotsPragma($list) : null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/ResolverTrait.php b/vendor/opis/json-schema/src/Parsers/ResolverTrait.php new file mode 100644 index 0000000..0c66340 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/ResolverTrait.php @@ -0,0 +1,38 @@ + $super) { + if (!isset($list[$sub]) && isset($list[$super])) { + $list[$sub] = $list[$super]; + } + } + + return $list; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/SchemaParser.php b/vendor/opis/json-schema/src/Parsers/SchemaParser.php new file mode 100644 index 0000000..4eef186 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/SchemaParser.php @@ -0,0 +1,644 @@ + true, + 'allowFormats' => true, + 'allowMappers' => true, + 'allowTemplates' => true, + 'allowGlobals' => true, + 'allowDefaults' => true, + 'allowSlots' => true, + 'allowKeywordValidators' => true, + 'allowPragmas' => true, + + 'allowDataKeyword' => true, + 'allowKeywordsAlongsideRef' => false, + 'allowUnevaluated' => true, + 'allowRelativeJsonPointerInRef' => true, + 'allowExclusiveMinMaxAsBool' => true, + + 'keepDependenciesKeyword' => true, + 'keepAdditionalItemsKeyword' => true, + + 'decodeContent' => ['06', '07'], + 'defaultDraft' => self::DEFAULT_DRAFT, + + 'varRefKey' => '$ref', + 'varEachKey' => '$each', + 'varDefaultKey' => 'default', + ]; + + /** @var array */ + protected array $options; + + /** @var Draft[] */ + protected array $drafts; + + /** @var array */ + protected array $resolvers; + + /** + * @param array $resolvers + * @param array $options + * @param Vocabulary|null $extraVocabulary + */ + public function __construct( + array $resolvers = [], + array $options = [], + ?Vocabulary $extraVocabulary = null + ) + { + if ($options) { + $this->options = $options + self::DEFAULT_OPTIONS; + } else { + $this->options = self::DEFAULT_OPTIONS; + } + + $this->resolvers = $this->getResolvers($resolvers); + + $this->drafts = $this->getDrafts($extraVocabulary ?? new DefaultVocabulary()); + } + + /** + * @param Vocabulary|null $extraVocabulary + * @return array + */ + protected function getDrafts(?Vocabulary $extraVocabulary): array + { + return [ + '06' => new Draft06($extraVocabulary), + '07' => new Draft07($extraVocabulary), + '2019-09' => new Draft201909($extraVocabulary), + '2020-12' => new Draft202012($extraVocabulary), + ]; + } + + /** + * @param array $resolvers + * @return array + */ + protected function getResolvers(array $resolvers): array + { + if (!array_key_exists('format', $resolvers)) { + $resolvers['format'] = new FormatResolver(); + } + + if (!array_key_exists('contentEncoding', $resolvers)) { + $resolvers['contentEncoding'] = new ContentEncodingResolver(); + } + + if (!array_key_exists('contentMediaType', $resolvers)) { + $resolvers['contentMediaType'] = new ContentMediaTypeResolver(); + } + + if (!array_key_exists('$filters', $resolvers)) { + $resolvers['$filters'] = new FilterResolver(); + } + + return $resolvers; + } + + /** + * @param string $name + * @param null $default + * @return mixed|null + */ + public function option(string $name, $default = null) + { + return $this->options[$name] ?? $default; + } + + /** + * @param string $name + * @param $value + * @return $this + */ + public function setOption(string $name, $value): self + { + $this->options[$name] = $value; + + return $this; + } + + /** + * @return array + */ + public function getOptions(): array + { + return $this->options; + } + + /** + * @param string $name + * @param $resolver + * @return $this + */ + public function setResolver(string $name, $resolver): self + { + $this->resolvers[$name] = $resolver; + + return $this; + } + + /** + * @return null|FilterResolver + */ + public function getFilterResolver(): ?FilterResolver + { + return $this->getResolver('$filters'); + } + + /** + * @param null|FilterResolver $resolver + * @return $this + */ + public function setFilterResolver(?FilterResolver $resolver): self + { + return $this->setResolver('$filters', $resolver); + } + + /** + * @return null|FormatResolver + */ + public function getFormatResolver(): ?FormatResolver + { + return $this->getResolver('format'); + } + + /** + * @param FormatResolver|null $resolver + * @return $this + */ + public function setFormatResolver(?FormatResolver $resolver): self + { + return $this->setResolver('format', $resolver); + } + + /** + * @return null|ContentEncodingResolver + */ + public function getContentEncodingResolver(): ?ContentEncodingResolver + { + return $this->getResolver('contentEncoding'); + } + + /** + * @param ContentEncodingResolver|null $resolver + * @return $this + */ + public function setContentEncodingResolver(?ContentEncodingResolver $resolver): self + { + return $this->setResolver('contentEncoding', $resolver); + } + + /** + * @return null|ContentMediaTypeResolver + */ + public function getMediaTypeResolver(): ?ContentMediaTypeResolver + { + return $this->getResolver('contentMediaType'); + } + + /** + * @param ContentMediaTypeResolver|null $resolver + * @return $this + */ + public function setMediaTypeResolver(?ContentMediaTypeResolver $resolver): self + { + return $this->setResolver('contentMediaType', $resolver); + } + + /** + * @return string + */ + public function defaultDraftVersion(): string + { + return $this->option('defaultDraft', self::DEFAULT_DRAFT); + } + + /** + * @param string $draft + * @return $this + */ + public function setDefaultDraftVersion(string $draft): self + { + return $this->setOption('defaultDraft', $draft); + } + + /** + * @param string $schema + * @return string|null + */ + public function parseDraftVersion(string $schema): ?string + { + if (!preg_match(self::DRAFT_REGEX, $schema, $m)) { + return null; + } + + return $m[1] ?? null; + } + + /** + * @param object $schema + * @return string|null + */ + public function parseId(object $schema): ?string + { + if (property_exists($schema, '$id') && is_string($schema->{'$id'})) { + return $schema->{'$id'}; + } + + return null; + } + + /** + * @param object $schema + * @param string $draft + * @return string|null + */ + public function parseAnchor(object $schema, string $draft): ?string + { + if (!property_exists($schema, '$anchor') || + !isset($this->drafts[$draft]) || + !$this->drafts[$draft]->supportsAnchorId()) { + return null; + } + + $anchor = $schema->{'$anchor'}; + + if (!is_string($anchor) || !preg_match(self::ANCHOR_REGEX, $anchor)) { + return null; + } + + return $anchor; + } + + /** + * @param object $schema + * @return string|null + */ + public function parseSchemaDraft(object $schema): ?string + { + if (!property_exists($schema, '$schema') || !is_string($schema->{'$schema'})) { + return null; + } + + return $this->parseDraftVersion($schema->{'$schema'}); + } + + /** + * @param object $schema + * @param Uri $id + * @param callable $handle_id + * @param callable $handle_object + * @param string|null $draft + * @return Schema|null + */ + public function parseRootSchema( + object $schema, + Uri $id, + callable $handle_id, + callable $handle_object, + ?string $draft = null + ): ?Schema + { + $existent = false; + if (property_exists($schema, '$id')) { + $existent = true; + $id = Uri::parse($schema->{'$id'}, true); + } + + if ($id instanceof Uri) { + if ($id->fragment() === null) { + $id = Uri::merge($id, null, true); + } + } else { + throw new ParseException('Root schema id must be an URI', new SchemaInfo($schema, $id)); + } + + if (!$id->isAbsolute()) { + throw new ParseException('Root schema id must be an absolute URI', new SchemaInfo($schema, $id)); + } + + if ($id->fragment() !== '') { + throw new ParseException('Root schema id must have an empty fragment or none', new SchemaInfo($schema, $id)); + } + + // Check if id exists + if ($resolved = $handle_id($id)) { + return $resolved; + } + + if (property_exists($schema, '$schema')) { + if (!is_string($schema->{'$schema'})) { + throw new ParseException('Schema draft must be a string', new SchemaInfo($schema, $id)); + } + $draft = $this->parseDraftVersion($schema->{'$schema'}); + } + + if ($draft === null) { + $draft = $this->defaultDraftVersion(); + } + + if (!$existent) { + $schema->{'$id'} = (string)$id; + } + + $resolved = $handle_object($schema, $id, $draft); + + if (!$existent) { + unset($schema->{'$id'}); + } + + return $resolved; + } + + /** + * @param SchemaInfo $info + * @return Schema + */ + public function parseSchema(SchemaInfo $info): Schema + { + if ($info->isBoolean()) { + return new BooleanSchema($info); + } + + try { + return $this->parseSchemaObject($info); + } catch (SchemaException $exception) { + return new ExceptionSchema($info, $exception); + } + } + + /** + * @param string $version + * @return Draft|null + */ + public function draft(string $version): ?Draft + { + return $this->drafts[$version] ?? null; + } + + /** + * @param Draft $draft + * @return $this + */ + public function addDraft(Draft $draft): self + { + $this->drafts[$draft->version()] = $draft; + + return $this; + } + + /** + * @return string[] + */ + public function supportedDrafts(): array + { + return array_keys($this->drafts); + } + + /** + * @param array $options + * @return $this + */ + protected function setOptions(array $options): self + { + $this->options = $options + $this->options; + + return $this; + } + + /** + * @param string $name + * @return mixed|null + */ + protected function getResolver(string $name) + { + $resolver = $this->resolvers[$name] ?? null; + + if (!is_object($resolver)) { + return null; + } + + return $resolver; + } + + /** + * @param SchemaInfo $info + * @return Schema + */ + protected function parseSchemaObject(SchemaInfo $info): Schema + { + $draftObject = $this->draft($info->draft()); + + if ($draftObject === null) { + throw new ParseException("Unsupported draft-{$info->draft()}", $info); + } + + /** @var object $schema */ + $schema = $info->data(); + + // Check id + if (property_exists($schema, '$id')) { + $id = $info->id(); + if ($id === null || !$id->isAbsolute()) { + throw new ParseException('Schema id must be a valid URI', $info); + } + } + + if ($hasRef = property_exists($schema, '$ref')) { + if ($this->option('allowKeywordsAlongsideRef') || $draftObject->allowKeywordsAlongsideRef()) { + $hasRef = false; + } + } + + $shared = (object) []; + + if ($this->option('allowKeywordValidators')) { + $keywordValidator = $this->parseKeywordValidators($info, $draftObject->keywordValidators(), $shared); + } else { + $keywordValidator = null; + } + + return $this->parseSchemaKeywords($info, $keywordValidator, $draftObject->keywords(), $shared, $hasRef); + } + + /** + * @param SchemaInfo $info + * @param KeywordValidatorParser[] $keywordValidators + * @param object $shared + * @return KeywordValidator|null + */ + protected function parseKeywordValidators(SchemaInfo $info, array $keywordValidators, object $shared): ?KeywordValidator + { + $last = null; + + while ($keywordValidators) { + /** @var KeywordValidatorParser $keywordValidator */ + $keywordValidator = array_pop($keywordValidators); + if ($keywordValidator && ($keyword = $keywordValidator->parse($info, $this, $shared))) { + $keyword->setNext($last); + $last = $keyword; + unset($keyword); + } + unset($keywordValidator); + } + + return $last; + } + + /** + * @param SchemaInfo $info + * @param KeywordValidator|null $keywordValidator + * @param KeywordParser[] $parsers + * @param object $shared + * @param bool $hasRef + * @return Schema + */ + protected function parseSchemaKeywords(SchemaInfo $info, ?KeywordValidator $keywordValidator, + array $parsers, object $shared, bool $hasRef = false): Schema + { + /** @var Keyword[] $prepend */ + $prepend = []; + /** @var Keyword[] $append */ + $append = []; + /** @var Keyword[] $before */ + $before = []; + /** @var Keyword[] $after */ + $after = []; + /** @var Keyword[][] $types */ + $types = []; + /** @var Keyword[] $ref */ + $ref = []; + + if ($hasRef) { + foreach ($parsers as $parser) { + $kType = $parser->type(); + + if ($kType === KeywordParser::TYPE_APPEND) { + $container = &$append; + } elseif ($kType === KeywordParser::TYPE_AFTER_REF) { + $container = &$ref; + } elseif ($kType === KeywordParser::TYPE_PREPEND) { + $container = &$prepend; + } else { + continue; + } + + if ($keyword = $parser->parse($info, $this, $shared)) { + $container[] = $keyword; + } + + unset($container, $keyword, $kType); + } + } else { + foreach ($parsers as $parser) { + $keyword = $parser->parse($info, $this, $shared); + if ($keyword === null) { + continue; + } + + $kType = $parser->type(); + + switch ($kType) { + case KeywordParser::TYPE_PREPEND: + $prepend[] = $keyword; + break; + case KeywordParser::TYPE_APPEND: + $append[] = $keyword; + break; + case KeywordParser::TYPE_BEFORE: + $before[] = $keyword; + break; + case KeywordParser::TYPE_AFTER: + $after[] = $keyword; + break; + case KeywordParser::TYPE_AFTER_REF: + $ref[] = $keyword; + break; + default: + if (!isset($types[$kType])) { + $types[$kType] = []; + } + $types[$kType][] = $keyword; + break; + + } + } + } + + unset($shared); + + if ($prepend) { + $before = array_merge($prepend, $before); + } + unset($prepend); + + if ($ref) { + $after = array_merge($after, $ref); + } + unset($ref); + + if ($append) { + $after = array_merge($after, $append); + } + unset($append); + + if (empty($before)) { + $before = null; + } + if (empty($after)) { + $after = null; + } + if (empty($types)) { + $types = null; + } + + if (empty($types) && empty($before) && empty($after)) { + return new EmptySchema($info, $keywordValidator); + } + + return new ObjectSchema($info, $keywordValidator, $types, $before, $after); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/VariablesTrait.php b/vendor/opis/json-schema/src/Parsers/VariablesTrait.php new file mode 100644 index 0000000..6022fb9 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/VariablesTrait.php @@ -0,0 +1,41 @@ +option('varRefKey', '$ref'), + $parser->option('varEachKey', '$each'), + $parser->option('varDefaultKey', 'default') + ); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Parsers/Vocabulary.php b/vendor/opis/json-schema/src/Parsers/Vocabulary.php new file mode 100644 index 0000000..0f83fe2 --- /dev/null +++ b/vendor/opis/json-schema/src/Parsers/Vocabulary.php @@ -0,0 +1,126 @@ +keywords = $keywords; + $this->keywordValidators = $keywordValidators; + $this->pragmas = $pragmas; + } + + /** + * @return KeywordParser[] + */ + public function keywords(): array + { + return $this->keywords; + } + + /** + * @return KeywordValidatorParser[] + */ + public function keywordValidators(): array + { + return $this->keywordValidators; + } + + /** + * @return PragmaParser[] + */ + public function pragmas(): array + { + return $this->pragmas; + } + + /** + * @param KeywordParser $keyword + * @return Vocabulary + */ + public function appendKeyword(KeywordParser $keyword): self + { + $this->keywords[] = $keyword; + return $this; + } + + /** + * @param KeywordParser $keyword + * @return Vocabulary + */ + public function prependKeyword(KeywordParser $keyword): self + { + array_unshift($this->keywords, $keyword); + return $this; + } + + /** + * @param KeywordValidatorParser $keywordValidatorParser + * @return Vocabulary + */ + public function appendKeywordValidator(KeywordValidatorParser $keywordValidatorParser): self + { + $this->keywordValidators[] = $keywordValidatorParser; + return $this; + } + + /** + * @param KeywordValidatorParser $keywordValidator + * @return Vocabulary + */ + public function prependKeywordValidator(KeywordValidatorParser $keywordValidator): self + { + array_unshift($this->keywordValidators, $keywordValidator); + return $this; + } + + /** + * @param PragmaParser $pragma + * @return Vocabulary + */ + public function appendPragma(PragmaParser $pragma): self + { + $this->pragmas[] = $pragma; + return $this; + } + + /** + * @param PragmaParser $pragma + * @return Vocabulary + */ + public function prependPragma(PragmaParser $pragma): self + { + array_unshift($this->pragmas, $pragma); + return $this; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Pragma.php b/vendor/opis/json-schema/src/Pragma.php new file mode 100644 index 0000000..fc8860b --- /dev/null +++ b/vendor/opis/json-schema/src/Pragma.php @@ -0,0 +1,33 @@ +cast = $cast; + $this->func = $this->getCastFunction($cast); + } + + /** + * @inheritDoc + */ + public function enter(ValidationContext $context) + { + $currentType = $context->currentDataType(); + if ($currentType !== null && Helper::jsonTypeMatches($currentType, $this->cast)) { + // Cast not needed + return $this; + } + unset($currentType); + + $currentData = $context->currentData(); + + $context->setCurrentData(($this->func)($currentData)); + + return $currentData; + } + + /** + * @inheritDoc + */ + public function leave(ValidationContext $context, $data): void + { + if ($data !== $this) { + $context->setCurrentData($data); + } + } + + /** + * @param string $type + * @return callable + */ + protected function getCastFunction(string $type): callable + { + $f = 'toNull'; + + switch ($type) { + case 'integer': + $f = 'toInteger'; + break; + case 'number': + $f = 'toNumber'; + break; + case 'string': + $f = 'toString'; + break; + case 'array': + $f = 'toArray'; + break; + case 'object': + $f = 'toObject'; + break; + case 'boolean': + $f = 'toBoolean'; + break; + } + + return [$this, $f]; + } + + /** + * @param $value + * @return int|null + */ + public function toInteger($value): ?int + { + if ($value === null) { + return 0; + } + + return is_scalar($value) ? intval($value) : null; + } + + /** + * @param $value + * @return float|null + */ + public function toNumber($value): ?float + { + if ($value === null) { + return 0.0; + } + + return is_scalar($value) ? floatval($value) : null; + } + + /** + * @param $value + * @return string|null + */ + public function toString($value): ?string + { + if ($value === null) { + return ''; + } + + if (is_scalar($value)) { + return (string) $value; + } + + return null; + } + + /** + * @param $value + * @return array|null + */ + public function toArray($value): ?array + { + if ($value === null) { + return []; + } + + if (is_scalar($value)) { + return [$value]; + } + + if (is_array($value)) { + return array_values($value); + } + + if (is_object($value)) { + return array_values(get_object_vars($value)); + } + + return null; + } + + /** + * @param $value + * @return object|null + */ + public function toObject($value): ?object + { + if (is_object($value) || is_array($value)) { + return (object) $value; + } + + return null; + } + + /** + * @param $value + * @return bool + */ + public function toBoolean($value): bool + { + if ($value === null) { + return false; + } + if (is_string($value)) { + return !($value === ''); + } + if (is_object($value)) { + return count(get_object_vars($value)) > 0; + } + return boolval($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Pragmas/GlobalsPragma.php b/vendor/opis/json-schema/src/Pragmas/GlobalsPragma.php new file mode 100644 index 0000000..e1233cf --- /dev/null +++ b/vendor/opis/json-schema/src/Pragmas/GlobalsPragma.php @@ -0,0 +1,61 @@ +globals = $globals; + } + + /** + * @inheritDoc + */ + public function enter(ValidationContext $context) + { + $resolved = (array) $this->globals->resolve($context->rootData(), $context->currentDataPath()); + if (!$resolved) { + return null; + } + + $data = $context->globals(); + $context->setGlobals($resolved, false); + return $data; + } + + /** + * @inheritDoc + */ + public function leave(ValidationContext $context, $data): void + { + if ($data === null) { + return; + } + $context->setGlobals($data, true); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Pragmas/MaxErrorsPragma.php b/vendor/opis/json-schema/src/Pragmas/MaxErrorsPragma.php new file mode 100644 index 0000000..0d14626 --- /dev/null +++ b/vendor/opis/json-schema/src/Pragmas/MaxErrorsPragma.php @@ -0,0 +1,55 @@ +maxErrors = $maxErrors; + } + + /** + * @inheritDoc + */ + public function enter(ValidationContext $context) + { + $data = $context->maxErrors(); + $context->setMaxErrors($this->maxErrors); + return $data; + } + + /** + * @inheritDoc + */ + public function leave(ValidationContext $context, $data): void + { + if ($data === null) { + return; + } + $context->setMaxErrors($data); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Pragmas/SlotsPragma.php b/vendor/opis/json-schema/src/Pragmas/SlotsPragma.php new file mode 100644 index 0000000..7806a75 --- /dev/null +++ b/vendor/opis/json-schema/src/Pragmas/SlotsPragma.php @@ -0,0 +1,52 @@ +slots = $slots; + } + + /** + * @inheritDoc + */ + public function enter(ValidationContext $context) + { + $data = $context->slots(); + $context->setSlots($data ? $this->slots + $data : $this->slots); + return $data; + } + + /** + * @inheritDoc + */ + public function leave(ValidationContext $context, $data): void + { + $context->setSlots($data); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Resolvers/ContentEncodingResolver.php b/vendor/opis/json-schema/src/Resolvers/ContentEncodingResolver.php new file mode 100644 index 0000000..8c49b83 --- /dev/null +++ b/vendor/opis/json-schema/src/Resolvers/ContentEncodingResolver.php @@ -0,0 +1,134 @@ + self::class . '::DecodeBinary', + 'base64' => self::class . '::DecodeBase64', + 'quoted-printable' => self::class . '::DecodeQuotedPrintable', + ]; + + $this->list = $list; + $this->defaultEncoding = $defaultEncoding; + } + + /** + * @param string $name + * @return callable|ContentEncoding|string|null + */ + public function resolve(string $name) + { + return $this->list[$name] ?? $this->defaultEncoding; + } + + /** + * @param string $name + * @param ContentEncoding $encoding + * @return ContentEncodingResolver + */ + public function register(string $name, ContentEncoding $encoding): self + { + $this->list[$name] = $encoding; + + return $this; + } + + /** + * @param string $name + * @param callable $encoding + * @return ContentEncodingResolver + */ + public function registerCallable(string $name, callable $encoding): self + { + $this->list[$name] = $encoding; + + return $this; + } + + /** + * @param string $name + * @return bool + */ + public function unregister(string $name): bool + { + if (isset($this->list[$name])) { + unset($this->list[$name]); + + return true; + } + + return false; + } + + /** + * @param callable|ContentEncoding|null $handler + * @return $this + */ + public function setDefaultHandler($handler): self + { + $this->defaultEncoding = $handler; + return $this; + } + + public function __serialize(): array + { + return [ + 'list' => $this->list, + 'defaultEncoding' => $this->defaultEncoding, + ]; + } + + public function __unserialize(array $data): void + { + $this->list = $data['list']; + $this->defaultEncoding = $data['defaultEncoding'] ?? null; + } + + public static function DecodeBinary(string $value): ?string + { + return $value; + } + + public static function DecodeBase64(string $value): ?string + { + $value = base64_decode($value, true); + + return is_string($value) ? $value : null; + } + + public static function DecodeQuotedPrintable(string $value): ?string + { + return quoted_printable_decode($value); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Resolvers/ContentMediaTypeResolver.php b/vendor/opis/json-schema/src/Resolvers/ContentMediaTypeResolver.php new file mode 100644 index 0000000..2b95799 --- /dev/null +++ b/vendor/opis/json-schema/src/Resolvers/ContentMediaTypeResolver.php @@ -0,0 +1,145 @@ + self::class . '::IsJsonEncoded', + ]; + + $this->media = $media; + $this->defaultMedia = $defaultMedia ?? self::class . '::IsEncodedAsType'; + } + + /** + * @param string $name + * @return callable|ContentMediaType|string|null + */ + public function resolve(string $name) + { + return $this->media[$name] ?? $this->defaultMedia; + } + + /** + * @param string $name + * @param ContentMediaType $media + * @return ContentMediaTypeResolver + */ + public function register(string $name, ContentMediaType $media): self + { + $this->media[$name] = $media; + + return $this; + } + + /** + * @param string $name + * @param callable $media + * @return ContentMediaTypeResolver + */ + public function registerCallable(string $name, callable $media): self + { + $this->media[$name] = $media; + + return $this; + } + + /** + * @param string $name + * @return bool + */ + public function unregister(string $name): bool + { + if (isset($this->media[$name])) { + unset($this->media[$name]); + + return true; + } + + return false; + } + + /** + * @param callable|ContentMediaType|null $handler + * @return ContentMediaTypeResolver + */ + public function setDefaultHandler($handler): self + { + $this->defaultMedia = $handler; + + return $this; + } + + public function __serialize(): array + { + return [ + 'media' => $this->media, + 'defaultMedia' => $this->defaultMedia, + ]; + } + + public function __unserialize(array $data): void + { + $this->media = $data['media']; + $this->defaultMedia = $data['defaultMedia']; + } + + public static function IsJsonEncoded(string $value, + /** @noinspection PhpUnusedParameterInspection */ string $type): bool + { + json_decode($value); + + return json_last_error() === JSON_ERROR_NONE; + } + + public static function IsEncodedAsType(string $value, string $type): bool + { + /** @var finfo|null|bool $finfo */ + static $finfo = false; + + if ($finfo === false) { + if (!class_exists(finfo::class)) { + $finfo = null; + return false; + } + $finfo = new finfo(FILEINFO_MIME_TYPE); + } elseif (!$finfo) { + return false; + } + + $r = $finfo->buffer($value); + + return $r == $type || $r == 'application/x-empty'; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Resolvers/FilterResolver.php b/vendor/opis/json-schema/src/Resolvers/FilterResolver.php new file mode 100644 index 0000000..d3687ef --- /dev/null +++ b/vendor/opis/json-schema/src/Resolvers/FilterResolver.php @@ -0,0 +1,265 @@ +separator = $ns_separator; + $this->defaultNS = $default_ns; + + $this->registerDefaultFilters(); + } + + /** + * You can override this to add/remove default filters + */ + protected function registerDefaultFilters(): void + { + $this->registerMultipleTypes("schema-exists", new SchemaExistsFilter()); + $this->registerMultipleTypes("data-exists", new DataExistsFilter()); + $this->registerMultipleTypes("global-exists", new GlobalVarExistsFilter()); + $this->registerMultipleTypes("slot-exists", new SlotExistsFilter()); + $this->registerMultipleTypes("filter-exists", new FilterExistsFilter()); + $this->registerMultipleTypes("format-exists", new FormatExistsFilter()); + + $cls = DateTimeFilters::class . "::"; + $this->registerCallable("string", "min-date", $cls . "MinDate"); + $this->registerCallable("string", "max-date", $cls . "MaxDate"); + $this->registerCallable("string", "not-date", $cls . "NotDate"); + $this->registerCallable("string", "min-time", $cls . "MinTime"); + $this->registerCallable("string", "max-time", $cls . "MaxTime"); + $this->registerCallable("string", "min-datetime", $cls . "MinDateTime"); + $this->registerCallable("string", "max-datetime", $cls . "MaxDateTime"); + + $cls = CommonFilters::class . "::"; + $this->registerCallable("string", "regex", $cls . "Regex"); + $this->registerMultipleTypes("equals", $cls . "Equals"); + } + + + /** + * @param string $name + * @param string $type + * @return Filter|callable|null + */ + public function resolve(string $name, string $type) + { + [$ns, $name] = $this->parseName($name); + + if (isset($this->filters[$ns][$name])) { + return $this->filters[$ns][$name][$type] ?? null; + } + + if (!isset($this->ns[$ns])) { + return null; + } + + $this->filters[$ns][$name] = $this->ns[$ns]->resolveAll($name); + + return $this->filters[$ns][$name][$type] ?? null; + } + + /** + * @param string $name + * @return Filter[]|callable[]|null + */ + public function resolveAll(string $name): ?array + { + [$ns, $name] = $this->parseName($name); + + if (isset($this->filters[$ns][$name])) { + return $this->filters[$ns][$name]; + } + + if (!isset($this->ns[$ns])) { + return null; + } + + return $this->filters[$ns][$name] = $this->ns[$ns]->resolveAll($name); + } + + /** + * @param string $type + * @param string $name + * @param Filter $filter + * @return FilterResolver + */ + public function register(string $type, string $name, Filter $filter): self + { + [$ns, $name] = $this->parseName($name); + + $this->filters[$ns][$name][$type] = $filter; + + return $this; + } + + /** + * @param string $name + * @param string|null $type + * @return bool + */ + public function unregister(string $name, ?string $type = null): bool + { + [$ns, $name] = $this->parseName($name); + if (!isset($this->filters[$ns][$name])) { + return false; + } + + if ($type === null) { + unset($this->filters[$ns][$name]); + + return true; + } + + if (isset($this->filters[$ns][$name][$type])) { + unset($this->filters[$ns][$name][$type]); + + return true; + } + + return false; + } + + /** + * @param string $name + * @param callable|Filter $filter + * @param array|null $types + * @return FilterResolver + */ + public function registerMultipleTypes(string $name, $filter, ?array $types = null): self + { + [$ns, $name] = $this->parseName($name); + + $types = $types ?? Helper::JSON_TYPES; + + foreach ($types as $type) { + $this->filters[$ns][$name][$type] = $filter; + } + + return $this; + } + + /** + * @param string $type + * @param string $name + * @param callable $filter + * @return FilterResolver + */ + public function registerCallable(string $type, string $name, callable $filter): self + { + [$ns, $name] = $this->parseName($name); + + $this->filters[$ns][$name][$type] = $filter; + + return $this; + } + + /** + * @param string $ns + * @param FilterResolver $resolver + * @return FilterResolver + */ + public function registerNS(string $ns, FilterResolver $resolver): self + { + $this->ns[$ns] = $resolver; + + return $this; + } + + /** + * @param string $ns + * @return bool + */ + public function unregisterNS(string $ns): bool + { + if (isset($this->filters[$ns])) { + unset($this->filters[$ns]); + unset($this->ns[$ns]); + + return true; + } + + if (isset($this->ns[$ns])) { + unset($this->ns[$ns]); + + return true; + } + + return false; + } + + public function __serialize(): array + { + return [ + 'separator' => $this->separator, + 'defaultNS' => $this->defaultNS, + 'ns' => $this->ns, + 'filters' => $this->filters, + ]; + } + + public function __unserialize(array $data): void + { + $this->separator = $data['separator']; + $this->defaultNS = $data['defaultNS']; + $this->ns = $data['ns']; + $this->filters = $data['filters']; + } + + /** + * @param string $name + * @return array + */ + protected function parseName(string $name): array + { + $name = strtolower($name); + + if (strpos($name, $this->separator) === false) { + return [$this->defaultNS, $name]; + } + + return explode($this->separator, $name, 2); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Resolvers/FormatResolver.php b/vendor/opis/json-schema/src/Resolvers/FormatResolver.php new file mode 100644 index 0000000..61a3fdc --- /dev/null +++ b/vendor/opis/json-schema/src/Resolvers/FormatResolver.php @@ -0,0 +1,143 @@ +formats = [ + 'string' => [ + 'date' => DateTimeFormats::class . '::date', + 'time' => DateTimeFormats::class . '::time', + 'date-time' => DateTimeFormats::class . '::dateTime', + 'duration' => DateTimeFormats::class . '::duration', + + 'uri' => UriFormats::class . '::uri', + 'uri-reference' => UriFormats::class . '::uriReference', + 'uri-template' => UriFormats::class . '::uriTemplate', + + 'regex' => Helper::class . '::isValidPattern', + 'ipv4' => MiscFormats::class . '::ipv4', + 'ipv6' => MiscFormats::class . '::ipv6', + 'uuid' => MiscFormats::class . '::uuid', + + 'email' => MiscFormats::class . '::email', + 'hostname' => Uri::class . '::isValidHost', + + 'json-pointer' => JsonPointer::class . '::isAbsolutePointer', + 'relative-json-pointer' => JsonPointer::class . '::isRelativePointer', + + 'idn-hostname' => IriFormats::class . '::idnHostname', + 'idn-email' => IriFormats::class . '::idnEmail', + 'iri' => IriFormats::class . '::iri', + 'iri-reference' => IriFormats::class . '::iriReference', + ], + ]; + } + + /** + * @param string $name + * @param string $type + * @return callable|Format|null + */ + public function resolve(string $name, string $type) + { + return $this->formats[$type][$name] ?? null; + } + + /** + * @param string $name + * @return Format[]|callable[]|null + */ + public function resolveAll(string $name): ?array + { + $list = null; + + foreach ($this->formats as $type => $items) { + if (isset($items[$name])) { + $list[$type] = $items[$name]; + } + } + + return $list; + } + + /** + * @param string $type + * @param string $name + * @param Format $format + * @return FormatResolver + */ + public function register(string $type, string $name, Format $format): self + { + $this->formats[$type][$name] = $format; + + return $this; + } + + /** + * @param string $type + * @param string $name + * @param callable $format + * @return FormatResolver + */ + public function registerCallable(string $type, string $name, callable $format): self + { + $this->formats[$type][$name] = $format; + + return $this; + } + + /** + * @param string $type + * @param string $name + * @return bool + */ + public function unregister(string $type, string $name): bool + { + if (isset($this->formats[$type][$name])) { + unset($this->formats[$type][$name]); + + return true; + } + + return false; + } + + public function __serialize(): array + { + return ['formats' => $this->formats]; + } + + public function __unserialize(array $data): void + { + $this->formats = $data['formats']; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Resolvers/SchemaResolver.php b/vendor/opis/json-schema/src/Resolvers/SchemaResolver.php new file mode 100644 index 0000000..93c7d0a --- /dev/null +++ b/vendor/opis/json-schema/src/Resolvers/SchemaResolver.php @@ -0,0 +1,342 @@ +isAbsolute()) { + return null; + } + + $scheme = $uri->scheme(); + if (isset($this->protocols[$scheme])) { + return ($this->protocols[$scheme])($uri); + } + + $id = (string) $uri; + if (isset($this->raw[$id])) { + return $this->raw[$id]; + } + + $path = $this->resolvePath($uri); + + if ($path === null || !is_file($path)) { + return null; + } + + $data = file_get_contents($path); + if (!is_string($data)) { + return null; + } + + $data = json_decode($data, false); + + return $data; + } + + /** + * @param bool|object|string $schema + * @param string|null $id + * @return bool + */ + public function registerRaw($schema, ?string $id = null): bool + { + if (is_string($schema)) { + $schema = json_decode($schema, false); + } + + if ($id !== null && strpos($id, '#') === false) { + $id .= '#'; + } + + if (is_bool($schema)) { + if ($id === null) { + return false; + } + $this->raw[$id] = $schema; + return true; + } + + if (!is_object($schema)) { + return false; + } + + + if ($id === null) { + if (!isset($schema->{'$id'}) || !is_string($schema->{'$id'})) { + return false; + } + + $id = $schema->{'$id'}; + if (strpos($id, '#') === false) { + $id .= '#'; + } + } + + $this->raw[$id] = $schema; + + return true; + } + + /** + * @param string $id + * @return bool + */ + public function unregisterRaw(string $id): bool + { + if (strpos($id, '#') === false) { + $id .= '#'; + } + + if (isset($this->raw[$id])) { + unset($this->raw[$id]); + return true; + } + + return false; + } + + /** + * @param string $id + * @param string $file + * @return SchemaResolver + */ + public function registerFile(string $id, string $file): self + { + if (strpos($id, '#') === false) { + $id .= '#'; + } + + $this->files[$id] = $file; + + return $this; + } + + /** + * @param string $id + * @return bool + */ + public function unregisterFile(string $id): bool + { + if (strpos($id, '#') === false) { + $id .= '#'; + } + + if (!isset($this->files[$id])) { + return false; + } + + unset($this->files[$id]); + + return true; + } + + /** + * @param string $scheme + * @param callable $handler + * @return SchemaResolver + */ + public function registerProtocol(string $scheme, callable $handler): self + { + $this->protocols[$scheme] = $handler; + + return $this; + } + + /** + * @param string $scheme + * @return bool + */ + public function unregisterProtocol(string $scheme): bool + { + if (isset($this->protocols[$scheme])) { + unset($this->protocols[$scheme]); + + return true; + } + + return false; + } + + /** + * @param string $scheme + * @param string $host + * @param string|null $dir + * @return SchemaResolver + */ + public function registerProtocolDir(string $scheme, string $host, ?string $dir): self + { + if ($dir === null) { + unset($this->dirs[$scheme][$host]); + } else { + $this->dirs[$scheme][$host] = rtrim($dir, '/'); + } + + return $this; + } + + /** + * @param string $scheme + * @return bool + */ + public function unregisterProtocolDirs(string $scheme): bool + { + if (isset($this->dirs[$scheme])) { + unset($this->dirs[$scheme]); + + return true; + } + + return false; + } + + /** + * @param string $prefix + * @param string $dir + * @return SchemaResolver + */ + public function registerPrefix(string $prefix, string $dir): self + { + $this->prefixes[$prefix] = rtrim($dir, '/'); + + // Sort + uksort($this->prefixes, [$this, 'sortPrefixKeys']); + + return $this; + } + + /** + * @param string $prefix + * @return SchemaResolver + */ + public function unregisterPrefix(string $prefix): self + { + if (isset($this->prefixes[$prefix])) { + unset($this->prefixes[$prefix]); + // Sort + uksort($this->prefixes, [$this, 'sortPrefixKeys']); + } + + return $this; + } + + + public function __serialize(): array + { + return [ + 'raw' => $this->raw, + 'protocols' => $this->protocols, + 'prefixes' => $this->prefixes, + 'dirs' => $this->dirs, + ]; + } + + public function __unserialize(array $data): void + { + $this->raw = $data['raw']; + $this->protocols = $data['protocols']; + $this->prefixes = $data['prefixes']; + $this->dirs = $data['dirs']; + } + + /** + * @param string $a + * @param string $b + * @return int + */ + protected function sortPrefixKeys(string $a, string $b): int + { + $la = strlen($a); + $lb = strlen($b); + + if ($lb > $la) { + return 1; + } + + if ($lb === $la) { + return $b < $a ? 1 : ($b === $a ? 0 : -1); + } + + return -1; + } + + /** + * @param Uri $uri + * @return string|null + */ + protected function resolvePath(Uri $uri): ?string + { + $id = (string)$uri; + + if (isset($this->files[$id])) { + return $this->files[$id]; + } + + $scheme = $uri->scheme(); + + if (isset($this->dirs[$scheme])) { + $host = (string)$uri->host(); + if (isset($this->dirs[$scheme][$host])) { + return $this->dirs[$scheme][$host] . '/' . ltrim($uri->path(), '/'); + } + unset($host); + } + + $path = null; + foreach ($this->prefixes as $prefix => $dir) { + if ($prefix === '' || strpos($id, $prefix) === 0) { + $path = substr($id, strlen($prefix)); + if ($path === false || $path === '') { + $path = null; + continue; + } + $path = Uri::parseComponents($path); + if ($path && isset($path['path'])) { + $path = $dir . '/' . ltrim($path['path'], '/'); + break; + } + $path = null; + } + } + + return $path; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Schema.php b/vendor/opis/json-schema/src/Schema.php new file mode 100644 index 0000000..821a6a0 --- /dev/null +++ b/vendor/opis/json-schema/src/Schema.php @@ -0,0 +1,28 @@ +dataCache = new SplObjectStorage(); + $this->parser = $parser ?? new SchemaParser(); + $this->resolver = $resolver; + $this->decodeJsonString = $decodeJsonString; + } + + public function baseUri(): ?Uri + { + return $this->base; + } + + public function setBaseUri(?Uri $uri): self + { + $this->base = $uri; + return $this; + } + + public function parser(): SchemaParser + { + return $this->parser; + } + + public function setParser(SchemaParser $parser): self + { + $this->parser = $parser; + + return $this; + } + + public function resolver(): ?SchemaResolver + { + return $this->resolver; + } + + public function setResolver(?SchemaResolver $resolver): self + { + $this->resolver = $resolver; + + return $this; + } + + /** + * @param object $data + * @param null $id + * @param string|null $draft + * @return Schema + */ + public function loadObjectSchema(object $data, $id = null, ?string $draft = null): Schema + { + // Check if already loaded + if ($schema = $this->checkExistingObject($data)) { + return $schema; + } + + if (!$id) { + $id = $this->createSchemaId($data); + } + + $handle_id = fn (Uri $id): ?Schema => $this->checkExistingUri($id); + + $handle_object = function (object $data, Uri $id, string $draft): ?Schema { + $this->handleObject($data, $id, null, null, [], $draft, (string)$id); + + return $this->checkExistingObject($data); + }; + + return $this->parser->parseRootSchema($data, Uri::parse($id, true), $handle_id, $handle_object, $draft); + } + + /** + * @param bool $data + * @param null $id + * @param string|null $draft + * @return Schema + */ + public function loadBooleanSchema(bool $data, $id = null, ?string $draft = null): Schema + { + if (!$id) { + $id = $this->createSchemaId($data); + } + + return $this->parser->parseSchema(new SchemaInfo($data, Uri::parse($id, true), null, null, [], $draft)); + } + + /** + * @param Uri $uri + * @return Schema|null + */ + public function loadSchemaById(Uri $uri): ?Schema + { + if (!$uri->isAbsolute()) { + if ($this->base === null || !$this->base->isAbsolute()) { + return null; + } + $uri = $this->base->resolveRef($uri); + } + + $fragment = $uri->fragment(); + if ($fragment === null) { + $uri = Uri::merge($uri, null, true); + $fragment = ''; + } + + $schema = $this->checkExistingUri($uri); + + if ($schema !== null) { + return $schema; + } + + if ($fragment === '') { + return $this->resolve($uri); + } + + $root = Uri::merge('#', $uri); + + // Check if already resolved + if (($schema = $this->checkExistingUri($root)) === null) { + // Try to resolve + if (($schema = $this->resolve($root)) === null) { + // Schema not found + return null; + } + } + + // Resolve json pointer + if ($fragment !== '' && $schema && $schema->info()->isObject() && + ($pointer = JsonPointer::parse($fragment)) && $pointer->isAbsolute()) { + $object = $pointer->data($schema->info()->data()); + if (is_bool($object)) { + $schema = $this->loadBooleanSchema($object, $uri, $schema->info()->draft()); + } elseif (is_object($object)) { + $schema = $this->loadObjectSchema($object, $uri, $schema->info()->draft()); + } else { + $schema = null; + } + if ($schema) { + $key = $this->cacheKey((string) $uri); + $this->uriCache[$key] = $schema; + return $schema; + } + } + + // Check fragment + return $this->checkExistingUri($uri); + } + + /** + * Clears internal cache + */ + public function clearCache(): void + { + $this->dataCache->removeAll($this->dataCache); + $this->uriCache = []; + } + + /** + * @param Uri $uri + * @return null|Schema + */ + protected function resolve(Uri $uri): ?Schema + { + if ($this->resolver === null) { + return null; + } + + $data = $this->resolver->resolve($uri); + + if ($this->decodeJsonString && is_string($data)) { + $data = json_decode($data, false); + } + + if (is_bool($data)) { + $this->handleBoolean($data, $uri, null, null, [], $this->parser->defaultDraftVersion(), (string)$uri); + + return $this->checkExistingUri($uri); + } + + if (is_object($data)) { + if ($data instanceof Schema) { + return $data; + } + + $this->handleObject($data, $uri, null, null, [], $this->parser->defaultDraftVersion(), (string)$uri); + + return $this->checkExistingObject($data); + } + + return null; + } + + /** + * @param object $data + * @return null|Schema + */ + protected function checkExistingObject(object $data): ?Schema + { + if (!$this->dataCache->contains($data)) { + return null; + } + + $schema = $this->dataCache[$data]; + + if ($schema instanceof LazySchema) { + $schema = $schema->schema(); + $this->dataCache[$data] = $schema; + } elseif (!($schema instanceof Schema)) { + $schema = null; + } + + return $schema; + } + + /** + * @param Uri $uri + * @return null|Schema + */ + protected function checkExistingUri(Uri $uri): ?Schema + { + if ($uri->fragment() === null || !$uri->isAbsolute()) { + return null; + } + + $key = $this->cacheKey((string)$uri); + + if (!isset($this->uriCache[$key])) { + return null; + } + + $schema = $this->uriCache[$key]; + + if (!($schema instanceof Schema)) { + return $this->uriCache[$key] = $this->checkExistingObject($schema); + } + + if ($schema instanceof LazySchema) { + $schema = $schema->schema(); + $this->uriCache[$key] = $schema; + } + + return $schema; + } + + /** + * @param bool $data + * @param Uri|null $id + * @param Uri|null $base + * @param Uri|null $root + * @param array $path + * @param string $draft + * @param string $pointer + */ + protected function handleBoolean( + bool $data, + ?Uri $id, + ?Uri $base, + ?Uri $root, + array $path, + string $draft, + string $pointer + ) + { + $key = $this->cacheKey($pointer); + if (isset($this->uriCache[$key])) { + return; + } + + $this->uriCache[$key] = $this->parser->parseSchema(new SchemaInfo($data, $id, $base, $root, $path, $draft)); + } + + /** + * @param array $data + * @param Uri $base + * @param Uri $root + * @param array $path + * @param string $draft + * @param string $pointer + */ + protected function handleArray(array $data, Uri $base, Uri $root, array $path, string $draft, string $pointer) + { + foreach ($data as $key => $value) { + if (!is_int($key)) { + continue; + } + + if (is_bool($value)) { + $this->handleBoolean($value, null, $base, $root, array_merge($path, [$key]), $draft, + $pointer . '/' . $key); + } elseif (is_array($value)) { + $this->handleArray($value, $base, $root, array_merge($path, [$key]), $draft, $pointer . '/' . $key); + } elseif (is_object($value)) { + $this->handleObject($value, null, $base, $root, array_merge($path, [$key]), $draft, + $pointer . '/' . $key); + } + } + } + + /** + * @param object $data + * @param Uri|null $id + * @param Uri|null $base + * @param Uri|null $root + * @param array $path + * @param string $draft + * @param string $pointer + */ + protected function handleObject( + object $data, + ?Uri $id, + ?Uri $base, + ?Uri $root, + array $path, + string $draft, + string $pointer + ) + { + $schema_id = $this->parser->parseId($data); + $schema_anchor = $this->parser->parseAnchor($data, $draft); + $draft = $this->parser->parseSchemaDraft($data) ?? $draft; + + if ($schema_id !== null) { + $id = Uri::merge($schema_id, $base, true); + } elseif ($schema_anchor !== null) { + $id = Uri::merge('#' . $schema_anchor, $base, true); + } + + $lazy = new LazySchema(new SchemaInfo($data, $id, $base, $root, $path, $draft), $this->parser); + + if ($id && $id->isAbsolute()) { + $key = $this->cacheKey((string)$id); + if (isset($this->uriCache[$key])) { + throw new DuplicateSchemaIdException($id, $data); + } + $this->uriCache[$key] = $lazy; + } + + // When $id and $anchor are both present add a reference to the same lazy object + if ($schema_id !== null && $schema_anchor !== null) { + $anchor_id = Uri::merge('#' . $schema_anchor, $id, true); + $key = $this->cacheKey((string)$anchor_id); + if (isset($this->uriCache[$key])) { + throw new DuplicateSchemaIdException($anchor_id, $data); + } + $this->uriCache[$key] = $lazy; + } + + $this->dataCache[$data] = $lazy; + $this->uriCache[$this->cacheKey($pointer)] = $lazy; + + if ($root === null) { + $root = $id; + } + + if ($base === null) { + $base = $id ?? $root; + } elseif ($id !== null) { + $base = $id; + } + + foreach ($data as $key => $value) { + if (!is_string($key)) { + continue; + } + if (is_bool($value)) { + $this->handleBoolean($value, null, $base, $root, array_merge($path, [$key]), $draft, + $pointer . '/' . JsonPointer::encodePath($key)); + } elseif (is_array($value)) { + $this->handleArray($value, $base, $root, array_merge($path, [$key]), $draft, + $pointer . '/' . JsonPointer::encodePath($key)); + } elseif (is_object($value)) { + $this->handleObject($value, null, $base, $root, array_merge($path, [$key]), $draft, + $pointer . '/' . JsonPointer::encodePath($key)); + } + } + } + + /** + * @param string $path + * @return string + */ + protected function cacheKey(string $path): string + { + return isset($path[32]) ? md5($path) : $path; + } + + /** + * @param bool|object $data + * @return string + */ + protected function createSchemaId($data): string + { + if (is_bool($data)) { + $data = $data ? 'true' : 'false'; + } else { + $data = spl_object_hash($data); + } + + return "schema:///{$data}.json"; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/SchemaValidator.php b/vendor/opis/json-schema/src/SchemaValidator.php new file mode 100644 index 0000000..a8b6e3e --- /dev/null +++ b/vendor/opis/json-schema/src/SchemaValidator.php @@ -0,0 +1,29 @@ +info = $info; + } + + /** + * @inheritDoc + */ + public function info(): SchemaInfo + { + return $this->info; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Schemas/BooleanSchema.php b/vendor/opis/json-schema/src/Schemas/BooleanSchema.php new file mode 100644 index 0000000..2c3a209 --- /dev/null +++ b/vendor/opis/json-schema/src/Schemas/BooleanSchema.php @@ -0,0 +1,49 @@ +data = $info->data(); + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context): ?ValidationError + { + if ($this->data) { + return null; + } + + return new ValidationError('', $this, DataInfo::fromContext($context), 'Data not allowed'); + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Schemas/EmptySchema.php b/vendor/opis/json-schema/src/Schemas/EmptySchema.php new file mode 100644 index 0000000..677f6b8 --- /dev/null +++ b/vendor/opis/json-schema/src/Schemas/EmptySchema.php @@ -0,0 +1,53 @@ +keywordValidator = $keywordValidator; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context): ?ValidationError + { + if (!$this->keywordValidator) { + return null; + } + + $context->pushSharedObject($this); + $error = $this->keywordValidator->validate($context); + $context->popSharedObject(); + + return $error; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Schemas/ExceptionSchema.php b/vendor/opis/json-schema/src/Schemas/ExceptionSchema.php new file mode 100644 index 0000000..9674597 --- /dev/null +++ b/vendor/opis/json-schema/src/Schemas/ExceptionSchema.php @@ -0,0 +1,48 @@ +exception = $exception; + } + + /** + * @inheritDoc + * @throws SchemaException + */ + public function validate(ValidationContext $context): ?ValidationError + { + throw $this->exception; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Schemas/LazySchema.php b/vendor/opis/json-schema/src/Schemas/LazySchema.php new file mode 100644 index 0000000..254d9bf --- /dev/null +++ b/vendor/opis/json-schema/src/Schemas/LazySchema.php @@ -0,0 +1,60 @@ +parser = $parser; + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context): ?ValidationError + { + return $this->schema()->validate($context); + } + + /** + * @return Schema + */ + public function schema(): Schema + { + if ($this->schema === null) { + $this->schema = $this->parser->parseSchema($this->info); + } + + return $this->schema; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Schemas/ObjectSchema.php b/vendor/opis/json-schema/src/Schemas/ObjectSchema.php new file mode 100644 index 0000000..1cc11be --- /dev/null +++ b/vendor/opis/json-schema/src/Schemas/ObjectSchema.php @@ -0,0 +1,120 @@ +types = $types; + $this->before = $before; + $this->after = $after; + $this->keywordValidator = $keywordValidator; + + if ($keywordValidator) { + while ($next = $keywordValidator->next()) { + $keywordValidator = $next; + } + $keywordValidator->setNext(new CallbackKeywordValidator([$this, 'doValidate'])); + } + } + + /** + * @inheritDoc + */ + public function validate(ValidationContext $context): ?ValidationError + { + $context->pushSharedObject($this); + $error = $this->keywordValidator ? $this->keywordValidator->validate($context) : $this->doValidate($context); + $context->popSharedObject(); + + return $error; + } + + /** + * @param ValidationContext $context + * @return null|ValidationError + *@internal + */ + public function doValidate(ValidationContext $context): ?ValidationError + { + if ($this->before && ($error = $this->applyKeywords($this->before, $context))) { + return $error; + } + + if ($this->types && ($type = $context->currentDataType())) { + if (isset($this->types[$type]) && ($error = $this->applyKeywords($this->types[$type], $context))) { + return $error; + } + + if (($type = Helper::getJsonSuperType($type)) && isset($this->types[$type])) { + if ($error = $this->applyKeywords($this->types[$type], $context)) { + return $error; + } + } + + unset($type); + } + + if ($this->after && ($error = $this->applyKeywords($this->after, $context))) { + return $error; + } + + return null; + } + + /** + * @param Keyword[] $keywords + * @param ValidationContext $context + * @return ValidationError|null + */ + protected function applyKeywords(array $keywords, ValidationContext $context): ?ValidationError + { + foreach ($keywords as $keyword) { + if ($error = $keyword->validate($context, $this)) { + return $error; + } + } + + return null; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Uri.php b/vendor/opis/json-schema/src/Uri.php new file mode 100644 index 0000000..3d6802f --- /dev/null +++ b/vendor/opis/json-schema/src/Uri.php @@ -0,0 +1,94 @@ +__toString(); + } + + /** + * @param string $uri + * @param bool $ensure_fragment + * @return static|null + */ + public static function parse(string $uri, bool $ensure_fragment = false): ?self + { + if ($ensure_fragment && strpos($uri, '#') === false) { + $uri .= '#'; + } + + return self::create($uri); + } + + /** + * @param string|array|static $uri + * @param string|array|static $base + * @param bool $ensure_fragment + * @return static|null + */ + public static function merge($uri, $base, bool $ensure_fragment = false): ?self + { + $uri = self::resolveComponents($uri); + + if ($uri === null) { + return null; + } + + if ($ensure_fragment && !isset($uri['fragment'])) { + $uri['fragment'] = ''; + } + + $base = self::resolveComponents($base); + + if (!$base) { + return new self($uri); + } + + return new self(self::mergeComponents($uri, $base)); + } + + /** + * @param bool $value + */ + public static function useNormalizedComponents(bool $value): void + { + self::$useNormalizedComponents = $value; + } +} diff --git a/vendor/opis/json-schema/src/ValidationContext.php b/vendor/opis/json-schema/src/ValidationContext.php new file mode 100644 index 0000000..e55470e --- /dev/null +++ b/vendor/opis/json-schema/src/ValidationContext.php @@ -0,0 +1,688 @@ +sender = $sender; + $this->rootData = $data; + $this->loader = $loader; + $this->parent = $parent; + $this->globals = $globals; + $this->slots = null; + $this->maxErrors = $max_errors; + $this->currentData = [ + [$data, false], + ]; + + if ($slots) { + $this->setSlots($slots); + } + } + + /** + * @param $data + * @param Schema|null $sender + * @param array|null $globals + * @param array|null $slots + * @param int|null $max_errors + * @return self + */ + public function newInstance( + $data, + ?Schema $sender, + ?array $globals = null, + ?array $slots = null, + ?int $max_errors = null + ): self { + return new self($data, $this->loader, $this, $sender, $globals ?? $this->globals, $slots ?? $this->slots, + $max_errors ?? $this->maxErrors); + } + + public function create( + Schema $sender, + ?Variables $mapper = null, + ?Variables $globals = null, + ?array $slots = null, + ?int $maxErrors = null + ): self { + if ($globals) { + $globals = $globals->resolve($this->rootData(), $this->currentDataPath()); + if (!is_array($globals)) { + $globals = (array)$globals; + } + $globals += $this->globals; + } else { + $globals = $this->globals; + } + + if ($mapper) { + $data = $mapper->resolve($this->rootData(), $this->currentDataPath()); + } else { + $data = $this->currentData(); + } + + return new self($data, $this->loader, $this, $sender, $globals, $slots ?? $this->slots, + $maxErrors ?? $this->maxErrors); + } + + public function sender(): ?Schema + { + return $this->sender; + } + + /** + * @return self|null + */ + public function parent(): ?self + { + return $this->parent; + } + + /** + * @return SchemaLoader + */ + public function loader(): SchemaLoader + { + return $this->loader; + } + + /** + * @return mixed + */ + public function rootData() + { + return $this->rootData; + } + + /** + * @return mixed + */ + public function currentData() + { + return $this->currentData[$this->pathIndex][0]; + } + + /** + * @param $value + */ + public function setCurrentData($value): void + { + $this->currentData[$this->pathIndex][0] = $value; + $this->currentData[$this->pathIndex][1] = false; + } + + /** + * @return string|null + */ + public function currentDataType(): ?string + { + $type = $this->currentData[$this->pathIndex][1]; + if ($type === false) { + $type = Helper::getJsonType($this->currentData[$this->pathIndex][0]); + $this->currentData[$this->pathIndex][1] = $type; + } + + return $type; + } + + public function fullDataPath(): array + { + if ($this->fullPath === null) { + if ($this->parent === null) { + return $this->currentDataPath; + } + $this->fullPath = array_merge($this->parent->fullDataPath(), $this->currentDataPath); + } + + return $this->fullPath; + } + + /** + * @return int[]|string[] + */ + public function currentDataPath(): array + { + return $this->currentDataPath; + } + + /** + * @param string|int $key + * @return $this + */ + public function pushDataPath($key): self + { + $this->currentDataPath[] = $key; + if ($this->fullPath !== null) { + $this->fullPath[] = $key; + } + + $data = $this->currentData[$this->pathIndex][0]; + + if (is_array($data)) { + $data = $data[$key] ?? null; + } elseif (is_object($data)) { + $data = $data->{$key} ?? null; + } else { + $data = null; + } + + $this->currentData[] = [$data, false]; + $this->pathIndex++; + + return $this; + } + + /** + * @return $this + */ + public function popDataPath(): self + { + if ($this->pathIndex < 1) { + return $this; + } + + if ($this->fullPath !== null) { + array_pop($this->fullPath); + } + array_pop($this->currentDataPath); + array_pop($this->currentData); + $this->pathIndex--; + + return $this; + } + + /** + * @return array + */ + public function globals(): array + { + return $this->globals; + } + + /** + * @param array $globals + * @param bool $overwrite + * @return $this + */ + public function setGlobals(array $globals, bool $overwrite = false): self + { + if ($overwrite) { + $this->globals = $globals; + } elseif ($globals) { + $this->globals = $globals + $this->globals; + } + + return $this; + } + + /** + * @return object[]|Schema[]|string[]|null + */ + public function slots(): ?array + { + return $this->slots; + } + + /** + * @param array|null $slots + * @return $this + */ + public function setSlots(?array $slots): self + { + if ($slots) { + $list = []; + + foreach ($slots as $name => $value) { + if (is_bool($value)) { + $value = $this->loader->loadBooleanSchema($value); + } elseif (is_object($value)) { + if ($value instanceof Schema) { + $list[$name] = $value; + continue; + } + $value = $this->loader->loadObjectSchema($value); + } elseif (is_string($value)) { + if (isset($this->slots[$value])) { + $value = $this->slots[$value]; + } elseif ($this->parent) { + $value = $this->parent->slot($value); + } + } + + if ($value instanceof Schema) { + $list[$name] = $value; + } + } + + $this->slots = $list; + } else { + $this->slots = null; + } + + return $this; + } + + /** + * @param string $name + * @return Schema|null + */ + public function slot(string $name): ?Schema + { + return $this->slots[$name] ?? null; + } + + /** + * @return int + */ + public function maxErrors(): int + { + return $this->maxErrors; + } + + /** + * @param int $max + * @return $this + */ + public function setMaxErrors(int $max): self + { + $this->maxErrors = $max; + + return $this; + } + + /* --------------------- */ + + /** + * @param Schema $schema + * @return $this + */ + public function pushSharedObject(Schema $schema): self + { + $unevaluated = !in_array($schema->info()->draft(), ['06', '07']); + if ($unevaluated && ($parser = $this->loader->parser()) && !$parser->option('allowUnevaluated', true)) { + $unevaluated = false; + } + + $this->shared[] = [ + 'schema' => $schema, + 'unevaluated' => $unevaluated, + 'object' => null, + ]; + $this->sharedIndex++; + + return $this; + } + + /** + * @return $this + */ + public function popSharedObject(): self + { + if ($this->sharedIndex < 0) { + return $this; + } + + $data = array_pop($this->shared); + $this->sharedIndex--; + + if ($data['unevaluated'] && $data['object']) { + if ($this->sharedIndex >= 0) { + $this->mergeUnevaluated($data['object']); + } elseif ($this->parent && $this->parent->sharedIndex >= 0) { + $this->parent->mergeUnevaluated($data['object']); + } + } + + return $this; + } + + /** + * @return object|null + */ + public function sharedObject(): ?object + { + if ($this->sharedIndex < 0) { + return null; + } + + return $this->shared[$this->sharedIndex]['object'] ??= (object)[]; + } + + public function schema(): ?Schema + { + return $this->shared[$this->sharedIndex]['schema'] ?? null; + } + + public function trackUnevaluated(): bool + { + return $this->shared[$this->sharedIndex]['unevaluated'] ?? false; + } + + protected function mergeUnevaluated(object $obj): void + { + switch ($this->currentDataType()) { + case 'object': + if (isset($obj->evaluatedProperties)) { + $this->addEvaluatedProperties($obj->evaluatedProperties); + } + break; + case 'array': + if (isset($obj->evaluatedItems)) { + $this->addEvaluatedItems($obj->evaluatedItems); + } + break; + } + } + + /* ----------------*/ + + public function getStringLength(): ?int + { + if ($this->currentDataType() !== 'string') { + return null; + } + + $shared = $this->sharedObject(); + + if (!isset($shared->stringLength)) { + $shared->stringLength = UnicodeString::from($this->currentData())->length(); + } + + return $shared->stringLength; + } + + public function setDecodedContent(string $content): bool + { + if ($this->currentDataType() !== 'string') { + return false; + } + + $this->sharedObject()->decodedContent = $content; + + return true; + } + + public function getDecodedContent(): ?string + { + if ($this->currentDataType() !== 'string') { + return null; + } + return $this->sharedObject()->decodedContent ?? $this->currentData(); + } + + public function getObjectProperties(): ?array + { + if ($this->currentDataType() !== 'object') { + return null; + } + + return $this->sharedObject()->objectProperties ??= array_keys(get_object_vars($this->currentData())); + } + + public function addCheckedProperties(?array $properties): bool + { + if (!$properties) { + return false; + } + + $shared = $this->sharedObject(); + + if (!isset($shared->checkedProperties)) { + $shared->checkedProperties = $properties; + } else { + $shared->checkedProperties = array_values(array_unique(array_merge($shared->checkedProperties, $properties))); + } + + return true; + } + + public function getCheckedProperties(): ?array + { + return $this->sharedObject()->checkedProperties ?? null; + } + + public function getUncheckedProperties(): ?array + { + $properties = $this->getObjectProperties(); + if (!$properties) { + return $properties; + } + + $checked = $this->sharedObject()->checkedProperties ?? null; + if (!$checked) { + return $properties; + } + + return array_values(array_diff($properties, $checked)); + } + + public function markAllAsEvaluatedProperties(): bool + { + return $this->addEvaluatedProperties($this->getObjectProperties()); + } + + public function addEvaluatedProperties(?array $properties): bool + { + if (!$properties || !($this->currentDataType() === 'object') || !$this->trackUnevaluated()) { + return false; + } + + $shared = $this->sharedObject(); + + if (!isset($shared->evaluatedProperties)) { + $shared->evaluatedProperties = $properties; + } else { + $shared->evaluatedProperties = array_values(array_unique(array_merge($shared->evaluatedProperties, $properties))); + } + + return true; + } + + public function getEvaluatedProperties(): ?array + { + return $this->sharedObject()->evaluatedProperties ?? null; + } + + public function getUnevaluatedProperties(): ?array + { + $properties = $this->getObjectProperties(); + if (!$properties) { + return $properties; + } + + $evaluated = $this->sharedObject()->evaluatedProperties ?? null; + if (!$evaluated) { + return $properties; + } + + return array_values(array_diff($properties, $evaluated)); + } + + public function markAllAsEvaluatedItems(): bool + { + return $this->addEvaluatedItems(range(0, count($this->currentData()))); + } + + public function markCountAsEvaluatedItems(int $count): bool + { + if (!$count) { + return false; + } + + return $this->addEvaluatedItems(range(0, $count)); + } + + public function addEvaluatedItems(?array $items): bool + { + if (!$items || !($this->currentDataType() === 'array') || !$this->trackUnevaluated()) { + return false; + } + + $shared = $this->sharedObject(); + + if (!isset($shared->evaluatedItems)) { + $shared->evaluatedItems = $items; + } else { + $shared->evaluatedItems = array_values(array_unique(array_merge($shared->evaluatedItems, $items), SORT_NUMERIC)); + } + + return true; + } + + public function getEvaluatedItems(): ?array + { + return $this->sharedObject()->evaluatedItems ?? null; + } + + public function getUnevaluatedItems(): ?array + { + if ($this->currentDataType() !== 'array') { + return null; + } + + $items = array_keys($this->currentData()); + if (!$items) { + return $items; + } + + $evaluated = $this->sharedObject()->evaluatedItems ?? null; + if (!$evaluated) { + return $items; + } + + return array_values(array_diff($items, $evaluated)); + } + + public function validateSchemaWithoutEvaluated( + Schema $schema, + ?int $maxErrors = null, + bool $reset_on_error_only = false, + ?ArrayObject $array = null + ): ?ValidationError { + $currentMaxErrors = $this->maxErrors; + + $this->maxErrors = $maxErrors ?? $currentMaxErrors; + + if ($this->trackUnevaluated()) { + $shared = $this->sharedObject(); + + $props = $shared->evaluatedProperties ?? null; + $items = $shared->evaluatedItems ?? null; + + $error = $schema->validate($this); + + if ($array) { + $value = null; + + if ($shared->evaluatedProperties ?? null) { + if ($props) { + if ($diff = array_diff($shared->evaluatedProperties, $props)) { + $value['properties'] = $diff; + } + } else { + $value['properties'] = $shared->evaluatedProperties; + } + } + + if ($shared->evaluatedItems ?? null) { + if ($items) { + if ($diff = array_diff($shared->evaluatedItems, $items)) { + $value['items'] = $diff; + } + } else { + $value['items'] = $shared->evaluatedItems; + } + } + + if ($value) { + $array[] = $value; + } + } + + if ($reset_on_error_only) { + if ($error) { + $shared->evaluatedProperties = $props; + $shared->evaluatedItems = $items; + } + } else { + $shared->evaluatedProperties = $props; + $shared->evaluatedItems = $items; + } + } else { + $error = $schema->validate($this); + } + + $this->maxErrors = $currentMaxErrors; + + return $error; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/ValidationResult.php b/vendor/opis/json-schema/src/ValidationResult.php new file mode 100644 index 0000000..08ca63f --- /dev/null +++ b/vendor/opis/json-schema/src/ValidationResult.php @@ -0,0 +1,53 @@ +error = $error; + } + + public function error(): ?ValidationError + { + return $this->error; + } + + public function isValid(): bool + { + return $this->error === null; + } + + public function hasError(): bool + { + return $this->error !== null; + } + + public function __toString(): string + { + if ($this->error) { + return $this->error->message(); + } + return ''; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Validator.php b/vendor/opis/json-schema/src/Validator.php new file mode 100644 index 0000000..73ae717 --- /dev/null +++ b/vendor/opis/json-schema/src/Validator.php @@ -0,0 +1,283 @@ +loader = $loader ?? new SchemaLoader(new SchemaParser(), new SchemaResolver(), true); + $this->maxErrors = $max_errors; + } + + /** + * @param $data + * @param bool|string|Uri|Schema|object $schema + * @param array|null $globals + * @param array|null $slots + * @return ValidationResult + */ + public function validate($data, $schema, ?array $globals = null, ?array $slots = null): ValidationResult + { + if (is_string($schema)) { + if ($uri = Uri::parse($schema, true)) { + $schema = $uri; + } else { + $schema = json_decode($schema, false); + } + } + + $error = null; + if (is_bool($schema)) { + $error = $this->dataValidation($data, $schema, $globals, $slots); + } elseif (is_object($schema)) { + if ($schema instanceof Uri) { + $error = $this->uriValidation($data, $schema, $globals, $slots); + } elseif ($schema instanceof Schema) { + $error = $this->schemaValidation($data, $schema, $globals, $slots); + } else { + $error = $this->dataValidation($data, $schema, $globals, $slots); + } + } else { + throw new InvalidArgumentException("Invalid schema"); + } + + return new ValidationResult($error); + } + + /** + * @param $data + * @param Uri|string $uri + * @param array|null $globals + * @param array|null $slots + * @return null|ValidationError + */ + public function uriValidation($data, $uri, ?array $globals = null, ?array $slots = null): ?ValidationError + { + if (is_string($uri)) { + $uri = Uri::parse($uri, true); + } + + if (!($uri instanceof Uri)) { + throw new InvalidArgumentException("Invalid uri"); + } + + if ($uri->fragment() === null) { + $uri = Uri::merge($uri, null, true); + } + + $schema = $this->loader->loadSchemaById($uri); + + if ($schema === null) { + throw new RuntimeException("Schema not found: $uri"); + } + + return $this->schemaValidation($data, $schema, $globals, $slots); + } + + /** + * @param $data + * @param string|object|bool $schema + * @param array|null $globals + * @param array|null $slots + * @param string|null $id + * @param string|null $draft + * @return ValidationError|null + */ + public function dataValidation( + $data, + $schema, + ?array $globals = null, + ?array $slots = null, + ?string $id = null, + ?string $draft = null + ): ?ValidationError + { + if (is_string($schema)) { + $schema = json_decode($schema, false); + } + + if ($schema === true) { + return null; + } + + if ($schema === false) { + $schema = $this->loader->loadBooleanSchema(false, $id, $draft); + } else { + if (!is_object($schema)) { + throw new InvalidArgumentException("Invalid schema"); + } + + $schema = $this->loader->loadObjectSchema($schema, $id, $draft); + } + + return $this->schemaValidation($data, $schema, $globals, $slots); + } + + /** + * @param $data + * @param Schema $schema + * @param array|null $globals + * @param array|null $slots + * @return null|ValidationError + */ + public function schemaValidation( + $data, + Schema $schema, + ?array $globals = null, + ?array $slots = null + ): ?ValidationError + { + return $schema->validate($this->createContext($data, $globals, $slots)); + } + + /** + * @param $data + * @param array|null $globals + * @param array|null $slots + * @return ValidationContext + */ + public function createContext($data, ?array $globals = null, ?array $slots = null): ValidationContext + { + if ($slots) { + $slots = $this->parseSlots($slots); + } + + return new ValidationContext($data, $this->loader, null, null, $globals ?? [], $slots, $this->maxErrors); + } + + /** + * @return SchemaParser + */ + public function parser(): SchemaParser + { + return $this->loader->parser(); + } + + /** + * @param SchemaParser $parser + * @return Validator + */ + public function setParser(SchemaParser $parser): self + { + $this->loader->setParser($parser); + + return $this; + } + + /** + * @return SchemaResolver|null + */ + public function resolver(): ?SchemaResolver + { + return $this->loader->resolver(); + } + + /** + * @param SchemaResolver|null $resolver + * @return Validator + */ + public function setResolver(?SchemaResolver $resolver): self + { + $this->loader->setResolver($resolver); + + return $this; + } + + /** + * @return SchemaLoader + */ + public function loader(): SchemaLoader + { + return $this->loader; + } + + /** + * @param SchemaLoader $loader + * @return Validator + */ + public function setLoader(SchemaLoader $loader): self + { + $this->loader = $loader; + + return $this; + } + + /** + * @return int + */ + public function getMaxErrors(): int + { + return $this->maxErrors; + } + + /** + * @param int $max_errors + * @return Validator + */ + public function setMaxErrors(int $max_errors): self + { + $this->maxErrors = $max_errors; + + return $this; + } + + /** + * @param array $slots + * @return array + */ + protected function parseSlots(array $slots): array + { + foreach ($slots as $name => &$value) { + if (!is_string($name)) { + unset($slots[$name]); + continue; + } + + if (is_string($value)) { + $value = Uri::parse($value, true); + } + + if ($value instanceof Uri) { + $value = $this->loader->loadSchemaById($value); + } elseif (is_bool($value)) { + $value = $this->loader->loadBooleanSchema($value); + } + + if (!is_object($value)) { + unset($slots[$name]); + } + + unset($value); + } + + return $slots; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Variables.php b/vendor/opis/json-schema/src/Variables.php new file mode 100644 index 0000000..a2682cb --- /dev/null +++ b/vendor/opis/json-schema/src/Variables.php @@ -0,0 +1,28 @@ +pointer = $pointer; + $this->each = $each; + $this->hasDefault = func_num_args() === 3; + $this->defaultValue = $default; + } + + /** + * @return JsonPointer + */ + public function pointer(): JsonPointer + { + return $this->pointer; + } + + /** + * @return null|Variables + */ + public function each(): ?Variables + { + return $this->each; + } + + /** + * @return bool + */ + public function hasDefaultValue(): bool + { + return $this->hasDefault; + } + + /** + * @return mixed|null + */ + public function defaultValue() + { + return $this->defaultValue; + } + + /** + * @inheritDoc + */ + public function resolve($data, array $path = []) + { + $resolved = $this->pointer->data($data, $path, $this); + if ($resolved === $this) { + return $this->defaultValue; + } + + if ($this->each && (is_array($resolved) || is_object($resolved))) { + $path = $this->pointer->absolutePath($path); + foreach ($resolved as $key => &$value) { + $path[] = $key; + $value = $this->each->resolve($data, $path); + array_pop($path); + unset($value); + } + } + + return $resolved; + } +} \ No newline at end of file diff --git a/vendor/opis/json-schema/src/Variables/VariablesContainer.php b/vendor/opis/json-schema/src/Variables/VariablesContainer.php new file mode 100644 index 0000000..163c9b5 --- /dev/null +++ b/vendor/opis/json-schema/src/Variables/VariablesContainer.php @@ -0,0 +1,162 @@ +keys = [ + 'ref' => $ref_key, + 'each' => $each_key, + 'default' => $default_key, + ]; + + if ($lazy) { + $this->vars = $data; + } else { + $this->parsed = true; + $this->vars = $this->parse($data); + } + } + + /** + * @inheritdoc + */ + public function resolve($data, array $path = []) + { + if (!$this->parsed) { + $this->vars = $this->parse($this->vars); + $this->parsed = true; + } + + if (!$this->hasRefs) { + // Nothing to resolve + return $this->vars; + } + + return $this->deepClone($this->vars, $data, $path); + } + + /** + * @param $vars + * @param $data + * @param string[]|int[] $path + * @return array|object|mixed + */ + private function deepClone($vars, $data, array $path) + { + $toObject = false; + if (is_object($vars)) { + if ($vars instanceof Variables) { + return $vars->resolve($data, $path); + } + $vars = get_object_vars($vars); + $toObject = true; + } elseif (!is_array($vars)) { + return $vars; + } + + foreach ($vars as &$var) { + if ($var !== null && !is_scalar($var)) { + $var = $this->deepClone($var, $data, $path); + } + unset($var); + } + + return $toObject ? (object)$vars : $vars; + } + + /** + * @param mixed $data + * @return mixed + */ + private function parse($data) + { + if (is_array($data)) { + return array_map([$this, 'parse'], $data); + } + + if (!is_object($data)) { + return $data; + } + + if ($vars = $this->parseRef($data)) { + $this->hasRefs = true; + + return $vars; + } + + return (object)array_map([$this, 'parse'], get_object_vars($data)); + } + + /** + * @param object $data + * @return null|Variables + */ + private function parseRef(object $data): ?Variables + { + if (!property_exists($data, $this->keys['ref'])) { + return null; + } + + $ref = $data->{$this->keys['ref']}; + if (!is_string($ref)) { + return null; + } + + $pointer = JsonPointer::parse($ref); + if ($pointer === null) { + return null; + } + + $each = null; + if (property_exists($data, $this->keys['each']) && is_object($data->{$this->keys['each']})) { + $each = new self($data->{$this->keys['each']}, !$this->parsed, $this->keys['ref'], $this->keys['each'], $this->keys['default']); + } + + if (property_exists($data, $this->keys['default'])) { + return new RefVariablesContainer($pointer, $each, $data->{$this->keys['default']}); + } + + return new RefVariablesContainer($pointer, $each); + } +} \ No newline at end of file diff --git a/vendor/opis/string/NOTICE b/vendor/opis/string/NOTICE new file mode 100644 index 0000000..d63600e --- /dev/null +++ b/vendor/opis/string/NOTICE @@ -0,0 +1,9 @@ +Opis String +Copyright 2018-2021 Zindex Software + +This product includes software developed at +Zindex Software (http://zindex.software). + +This software was originally developed by Marius Sarca and Sorin Sarca +(Copyright 2016-2018). The copyright info was changed with the permission +of the original authors. diff --git a/vendor/opis/string/res/ascii.php b/vendor/opis/string/res/ascii.php new file mode 100644 index 0000000..000a19f --- /dev/null +++ b/vendor/opis/string/res/ascii.php @@ -0,0 +1,751 @@ + 0x28, +0xAA => 0x61, +0xB0 => 0x30, +0xB2 => 0x32, +0xB3 => 0x33, +0xB5 => 0x75, +0xB9 => 0x31, +0xBA => 0x6F, +0xC0 => 0x41, +0xC1 => 0x41, +0xC2 => 0x41, +0xC3 => 0x41, +0xC4 => 0x41, +0xC5 => 0x41, +0xC6 => 0x41, +0xC7 => 0x43, +0xC8 => 0x45, +0xC9 => 0x45, +0xCA => 0x45, +0xCB => 0x45, +0xCC => 0x49, +0xCD => 0x49, +0xCE => 0x49, +0xCF => 0x49, +0xD0 => 0x44, +0xD1 => 0x4E, +0xD2 => 0x4F, +0xD3 => 0x4F, +0xD4 => 0x4F, +0xD5 => 0x4F, +0xD6 => 0x4F, +0xD8 => 0x4F, +0xD9 => 0x55, +0xDA => 0x55, +0xDB => 0x55, +0xDC => 0x55, +0xDD => 0x59, +0xDE => 0x54, +0xDF => 0x73, +0xE0 => 0x61, +0xE1 => 0x61, +0xE2 => 0x61, +0xE3 => 0x61, +0xE4 => 0x61, +0xE5 => 0x61, +0xE6 => 0x61, +0xE7 => 0x63, +0xE8 => 0x65, +0xE9 => 0x65, +0xEA => 0x65, +0xEB => 0x65, +0xEC => 0x69, +0xED => 0x69, +0xEE => 0x69, +0xEF => 0x69, +0xF0 => 0x64, +0xF1 => 0x6E, +0xF2 => 0x6F, +0xF3 => 0x6F, +0xF4 => 0x6F, +0xF5 => 0x6F, +0xF6 => 0x6F, +0xF8 => 0x6F, +0xF9 => 0x75, +0xFA => 0x75, +0xFB => 0x75, +0xFC => 0x75, +0xFD => 0x79, +0xFE => 0x74, +0xFF => 0x79, +0x100 => 0x41, +0x101 => 0x61, +0x102 => 0x41, +0x103 => 0x61, +0x104 => 0x41, +0x105 => 0x61, +0x106 => 0x43, +0x107 => 0x63, +0x108 => 0x43, +0x109 => 0x63, +0x10A => 0x43, +0x10B => 0x63, +0x10C => 0x43, +0x10D => 0x63, +0x10E => 0x44, +0x10F => 0x64, +0x110 => 0x44, +0x111 => 0x64, +0x112 => 0x45, +0x113 => 0x65, +0x114 => 0x45, +0x115 => 0x65, +0x116 => 0x45, +0x117 => 0x65, +0x118 => 0x45, +0x119 => 0x65, +0x11A => 0x45, +0x11B => 0x65, +0x11C => 0x47, +0x11D => 0x67, +0x11E => 0x47, +0x11F => 0x67, +0x120 => 0x47, +0x121 => 0x67, +0x122 => 0x47, +0x123 => 0x67, +0x124 => 0x48, +0x125 => 0x68, +0x126 => 0x48, +0x127 => 0x68, +0x128 => 0x49, +0x129 => 0x69, +0x12A => 0x49, +0x12B => 0x69, +0x12C => 0x49, +0x12D => 0x69, +0x12E => 0x49, +0x12F => 0x69, +0x130 => 0x49, +0x131 => 0x69, +0x132 => 0x49, +0x133 => 0x69, +0x134 => 0x4A, +0x135 => 0x6A, +0x136 => 0x6B, +0x137 => 0x6B, +0x138 => 0x6B, +0x139 => 0x4C, +0x13A => 0x6C, +0x13B => 0x4C, +0x13C => 0x6C, +0x13D => 0x4C, +0x13E => 0x6C, +0x13F => 0x4C, +0x140 => 0x6C, +0x141 => 0x4C, +0x142 => 0x6C, +0x143 => 0x4E, +0x144 => 0x6E, +0x145 => 0x4E, +0x146 => 0x6E, +0x147 => 0x4E, +0x148 => 0x6E, +0x149 => 0x6E, +0x14A => 0x4E, +0x14B => 0x6E, +0x14C => 0x4F, +0x14D => 0x6F, +0x14E => 0x4F, +0x14F => 0x6F, +0x150 => 0x4F, +0x151 => 0x6F, +0x152 => 0x4F, +0x153 => 0x6F, +0x154 => 0x52, +0x155 => 0x72, +0x156 => 0x52, +0x157 => 0x72, +0x158 => 0x52, +0x159 => 0x72, +0x15A => 0x53, +0x15B => 0x73, +0x15C => 0x53, +0x15D => 0x73, +0x15E => 0x53, +0x15F => 0x73, +0x160 => 0x53, +0x161 => 0x73, +0x162 => 0x54, +0x163 => 0x74, +0x164 => 0x54, +0x165 => 0x74, +0x166 => 0x54, +0x167 => 0x74, +0x168 => 0x55, +0x169 => 0x75, +0x16A => 0x55, +0x16B => 0x75, +0x16C => 0x55, +0x16D => 0x75, +0x16E => 0x55, +0x16F => 0x75, +0x170 => 0x55, +0x171 => 0x75, +0x172 => 0x55, +0x173 => 0x75, +0x174 => 0x57, +0x175 => 0x77, +0x176 => 0x59, +0x177 => 0x79, +0x178 => 0x59, +0x179 => 0x5A, +0x17A => 0x7A, +0x17B => 0x5A, +0x17C => 0x7A, +0x17D => 0x5A, +0x17E => 0x7A, +0x17F => 0x73, +0x189 => 0x44, +0x18A => 0x44, +0x18B => 0x44, +0x18C => 0x64, +0x18F => 0x45, +0x192 => 0x66, +0x1A0 => 0x4F, +0x1A1 => 0x6F, +0x1AF => 0x55, +0x1B0 => 0x75, +0x1CD => 0x41, +0x1CE => 0x61, +0x1CF => 0x49, +0x1D0 => 0x69, +0x1D1 => 0x4F, +0x1D2 => 0x6F, +0x1D3 => 0x55, +0x1D4 => 0x75, +0x1D5 => 0x55, +0x1D6 => 0x75, +0x1D7 => 0x55, +0x1D8 => 0x75, +0x1D9 => 0x55, +0x1DA => 0x75, +0x1DB => 0x55, +0x1DC => 0x75, +0x1FA => 0x41, +0x1FB => 0x61, +0x1FC => 0x41, +0x1FD => 0x61, +0x1FE => 0x4F, +0x1FF => 0x6F, +0x218 => 0x53, +0x219 => 0x73, +0x21A => 0x54, +0x21B => 0x74, +0x221 => 0x64, +0x256 => 0x64, +0x257 => 0x64, +0x259 => 0x65, +0x386 => 0x41, +0x388 => 0x45, +0x389 => 0x48, +0x38A => 0x49, +0x38C => 0x4F, +0x38E => 0x59, +0x38F => 0x57, +0x390 => 0x69, +0x391 => 0x41, +0x392 => 0x42, +0x393 => 0x47, +0x394 => 0x44, +0x395 => 0x45, +0x396 => 0x5A, +0x397 => 0x48, +0x398 => 0x4F, +0x399 => 0x49, +0x39A => 0x4B, +0x39B => 0x4C, +0x39C => 0x4D, +0x39D => 0x4E, +0x39E => 0x58, +0x39F => 0x4F, +0x3A0 => 0x50, +0x3A1 => 0x52, +0x3A3 => 0x53, +0x3A4 => 0x54, +0x3A5 => 0x59, +0x3A6 => 0x46, +0x3A7 => 0x58, +0x3A8 => 0x50, +0x3A9 => 0x57, +0x3AA => 0x49, +0x3AB => 0x59, +0x3AC => 0x61, +0x3AD => 0x65, +0x3AE => 0x68, +0x3AF => 0x69, +0x3B0 => 0x79, +0x3B1 => 0x61, +0x3B2 => 0x62, +0x3B3 => 0x67, +0x3B4 => 0x64, +0x3B5 => 0x65, +0x3B6 => 0x7A, +0x3B7 => 0x68, +0x3B8 => 0x6F, +0x3B9 => 0x69, +0x3BA => 0x6B, +0x3BB => 0x6C, +0x3BC => 0x6D, +0x3BD => 0x6E, +0x3BE => 0x78, +0x3BF => 0x6F, +0x3C0 => 0x70, +0x3C1 => 0x72, +0x3C2 => 0x73, +0x3C3 => 0x73, +0x3C4 => 0x74, +0x3C5 => 0x79, +0x3C6 => 0x66, +0x3C7 => 0x78, +0x3C8 => 0x70, +0x3C9 => 0x77, +0x3CA => 0x69, +0x3CB => 0x79, +0x3CC => 0x6F, +0x3CD => 0x79, +0x3CE => 0x77, +0x3D0 => 0x76, +0x3D1 => 0x74, +0x3D2 => 0x49, +0x401 => 0x45, +0x402 => 0x44, +0x404 => 0x45, +0x406 => 0x49, +0x407 => 0x49, +0x408 => 0x6A, +0x409 => 0x4C, +0x40A => 0x4E, +0x40F => 0x44, +0x410 => 0x41, +0x411 => 0x42, +0x412 => 0x56, +0x413 => 0x47, +0x414 => 0x44, +0x415 => 0x45, +0x416 => 0x5A, +0x417 => 0x5A, +0x418 => 0x49, +0x419 => 0x59, +0x41A => 0x4B, +0x41B => 0x4C, +0x41C => 0x4D, +0x41D => 0x4E, +0x41E => 0x4F, +0x41F => 0x50, +0x420 => 0x52, +0x421 => 0x53, +0x422 => 0x54, +0x423 => 0x55, +0x424 => 0x46, +0x425 => 0x4B, +0x426 => 0x54, +0x427 => 0x43, +0x428 => 0x53, +0x429 => 0x53, +0x42A => 0x62, +0x42B => 0x59, +0x42C => 0x62, +0x42D => 0x45, +0x42E => 0x59, +0x42F => 0x59, +0x430 => 0x61, +0x431 => 0x62, +0x432 => 0x76, +0x433 => 0x67, +0x434 => 0x64, +0x435 => 0x65, +0x436 => 0x7A, +0x437 => 0x7A, +0x438 => 0x69, +0x439 => 0x79, +0x43A => 0x6B, +0x43B => 0x6C, +0x43C => 0x6D, +0x43D => 0x6E, +0x43E => 0x6F, +0x43F => 0x70, +0x440 => 0x72, +0x441 => 0x73, +0x442 => 0x74, +0x443 => 0x75, +0x444 => 0x66, +0x445 => 0x6B, +0x446 => 0x74, +0x447 => 0x63, +0x448 => 0x73, +0x449 => 0x73, +0x44B => 0x79, +0x44D => 0x65, +0x44E => 0x79, +0x44F => 0x79, +0x451 => 0x65, +0x452 => 0x64, +0x454 => 0x65, +0x456 => 0x69, +0x457 => 0x69, +0x458 => 0x6A, +0x459 => 0x6C, +0x45A => 0x6E, +0x45F => 0x64, +0x490 => 0x47, +0x491 => 0x67, +0x4E8 => 0x4F, +0x622 => 0x61, +0x623 => 0x61, +0x624 => 0x6F, +0x625 => 0x65, +0x626 => 0x65, +0x627 => 0x61, +0x628 => 0x62, +0x62A => 0x74, +0x62B => 0x74, +0x62C => 0x6A, +0x62D => 0x68, +0x62E => 0x6B, +0x62F => 0x64, +0x630 => 0x74, +0x631 => 0x72, +0x632 => 0x7A, +0x633 => 0x73, +0x634 => 0x73, +0x635 => 0x73, +0x636 => 0x64, +0x637 => 0x74, +0x638 => 0x74, +0x639 => 0x61, +0x63A => 0x67, +0x641 => 0x66, +0x642 => 0x6B, +0x643 => 0x6B, +0x644 => 0x6C, +0x645 => 0x6D, +0x646 => 0x6E, +0x647 => 0x68, +0x648 => 0x6F, +0x64A => 0x79, +0x664 => 0x34, +0x665 => 0x35, +0x666 => 0x36, +0x67E => 0x70, +0x686 => 0x63, +0x698 => 0x7A, +0x6A9 => 0x6B, +0x6AF => 0x67, +0x6CC => 0x69, +0x6F0 => 0x30, +0x6F1 => 0x31, +0x6F2 => 0x32, +0x6F3 => 0x33, +0x6F4 => 0x34, +0x6F5 => 0x35, +0x6F6 => 0x36, +0x6F7 => 0x37, +0x6F8 => 0x38, +0x6F9 => 0x39, +0x905 => 0x61, +0x906 => 0x61, +0x907 => 0x69, +0x908 => 0x69, +0x909 => 0x75, +0x90A => 0x75, +0x90D => 0x65, +0x90F => 0x65, +0x910 => 0x61, +0x911 => 0x6F, +0x912 => 0x6F, +0x913 => 0x6F, +0x92C => 0x42, +0x932 => 0x4C, +0x1000 => 0x6B, +0x1002 => 0x67, +0x1005 => 0x73, +0x1007 => 0x7A, +0x1009 => 0x75, +0x100A => 0x69, +0x100B => 0x74, +0x100D => 0x64, +0x1010 => 0x74, +0x1012 => 0x64, +0x1014 => 0x6E, +0x1015 => 0x70, +0x1017 => 0x62, +0x1019 => 0x6D, +0x101A => 0x79, +0x101C => 0x6C, +0x101D => 0x77, +0x101F => 0x68, +0x1021 => 0x61, +0x1023 => 0x69, +0x1027 => 0x65, +0x102B => 0x61, +0x102C => 0x61, +0x102D => 0x6F, +0x102E => 0x69, +0x102F => 0x75, +0x1030 => 0x75, +0x1031 => 0x65, +0x1032 => 0x65, +0x103D => 0x77, +0x103E => 0x68, +0x10D0 => 0x61, +0x10D1 => 0x62, +0x10D2 => 0x67, +0x10D3 => 0x64, +0x10D4 => 0x65, +0x10D5 => 0x76, +0x10D6 => 0x7A, +0x10D7 => 0x74, +0x10D8 => 0x69, +0x10D9 => 0x6B, +0x10DA => 0x6C, +0x10DB => 0x6D, +0x10DC => 0x6E, +0x10DD => 0x6F, +0x10DE => 0x70, +0x10DF => 0x7A, +0x10E0 => 0x72, +0x10E1 => 0x73, +0x10E2 => 0x74, +0x10E3 => 0x75, +0x10E4 => 0x66, +0x10E5 => 0x6B, +0x10E6 => 0x67, +0x10E7 => 0x71, +0x10E8 => 0x73, +0x10E9 => 0x63, +0x10EA => 0x74, +0x10EB => 0x64, +0x10EC => 0x74, +0x10ED => 0x63, +0x10EE => 0x6B, +0x10EF => 0x6A, +0x10F0 => 0x68, +0x1D05 => 0x44, +0x1D06 => 0x44, +0x1D6D => 0x64, +0x1D81 => 0x64, +0x1D91 => 0x64, +0x1E9E => 0x53, +0x1EA0 => 0x41, +0x1EA1 => 0x61, +0x1EA2 => 0x41, +0x1EA3 => 0x61, +0x1EA4 => 0x41, +0x1EA5 => 0x61, +0x1EA6 => 0x41, +0x1EA7 => 0x61, +0x1EA8 => 0x41, +0x1EA9 => 0x61, +0x1EAA => 0x41, +0x1EAB => 0x61, +0x1EAC => 0x41, +0x1EAD => 0x61, +0x1EAE => 0x41, +0x1EAF => 0x61, +0x1EB0 => 0x41, +0x1EB1 => 0x61, +0x1EB2 => 0x41, +0x1EB3 => 0x61, +0x1EB4 => 0x41, +0x1EB5 => 0x61, +0x1EB6 => 0x41, +0x1EB7 => 0x61, +0x1EB8 => 0x45, +0x1EB9 => 0x65, +0x1EBA => 0x45, +0x1EBB => 0x65, +0x1EBC => 0x45, +0x1EBD => 0x65, +0x1EBE => 0x45, +0x1EBF => 0x65, +0x1EC0 => 0x45, +0x1EC1 => 0x65, +0x1EC2 => 0x45, +0x1EC3 => 0x65, +0x1EC4 => 0x45, +0x1EC5 => 0x65, +0x1EC6 => 0x45, +0x1EC7 => 0x65, +0x1EC8 => 0x49, +0x1EC9 => 0x69, +0x1ECA => 0x49, +0x1ECB => 0x69, +0x1ECC => 0x4F, +0x1ECD => 0x6F, +0x1ECE => 0x4F, +0x1ECF => 0x6F, +0x1ED0 => 0x4F, +0x1ED1 => 0x6F, +0x1ED2 => 0x4F, +0x1ED3 => 0x6F, +0x1ED4 => 0x4F, +0x1ED5 => 0x6F, +0x1ED6 => 0x4F, +0x1ED7 => 0x6F, +0x1ED8 => 0x4F, +0x1ED9 => 0x6F, +0x1EDA => 0x4F, +0x1EDB => 0x6F, +0x1EDC => 0x4F, +0x1EDD => 0x6F, +0x1EDE => 0x4F, +0x1EDF => 0x6F, +0x1EE0 => 0x4F, +0x1EE1 => 0x6F, +0x1EE2 => 0x4F, +0x1EE3 => 0x6F, +0x1EE4 => 0x55, +0x1EE5 => 0x75, +0x1EE6 => 0x55, +0x1EE7 => 0x75, +0x1EE8 => 0x55, +0x1EE9 => 0x75, +0x1EEA => 0x55, +0x1EEB => 0x75, +0x1EEC => 0x55, +0x1EED => 0x75, +0x1EEE => 0x55, +0x1EEF => 0x75, +0x1EF0 => 0x55, +0x1EF1 => 0x75, +0x1EF2 => 0x59, +0x1EF3 => 0x79, +0x1EF4 => 0x59, +0x1EF5 => 0x79, +0x1EF6 => 0x59, +0x1EF7 => 0x79, +0x1EF8 => 0x59, +0x1EF9 => 0x79, +0x1F00 => 0x61, +0x1F01 => 0x61, +0x1F02 => 0x61, +0x1F03 => 0x61, +0x1F04 => 0x61, +0x1F05 => 0x61, +0x1F06 => 0x61, +0x1F07 => 0x61, +0x1F08 => 0x41, +0x1F09 => 0x41, +0x1F0A => 0x41, +0x1F0B => 0x41, +0x1F0C => 0x41, +0x1F0D => 0x41, +0x1F0E => 0x41, +0x1F0F => 0x41, +0x1F10 => 0x65, +0x1F11 => 0x65, +0x1F12 => 0x65, +0x1F13 => 0x65, +0x1F14 => 0x65, +0x1F15 => 0x65, +0x1F18 => 0x45, +0x1F19 => 0x45, +0x1F1A => 0x45, +0x1F1B => 0x45, +0x1F1C => 0x45, +0x1F1D => 0x45, +0x1F30 => 0x69, +0x1F31 => 0x69, +0x1F32 => 0x69, +0x1F33 => 0x69, +0x1F34 => 0x69, +0x1F35 => 0x69, +0x1F36 => 0x69, +0x1F37 => 0x69, +0x1F38 => 0x49, +0x1F39 => 0x49, +0x1F3B => 0x49, +0x1F3C => 0x49, +0x1F3D => 0x49, +0x1F3E => 0x49, +0x1F3F => 0x49, +0x1F40 => 0x6F, +0x1F41 => 0x6F, +0x1F42 => 0x6F, +0x1F43 => 0x6F, +0x1F44 => 0x6F, +0x1F45 => 0x6F, +0x1F48 => 0x4F, +0x1F49 => 0x4F, +0x1F4A => 0x4F, +0x1F4B => 0x4F, +0x1F4C => 0x4F, +0x1F4D => 0x4F, +0x1F70 => 0x61, +0x1F72 => 0x65, +0x1F76 => 0x69, +0x1F78 => 0x6F, +0x1F80 => 0x61, +0x1F81 => 0x61, +0x1F82 => 0x61, +0x1F83 => 0x61, +0x1F84 => 0x61, +0x1F85 => 0x61, +0x1F86 => 0x61, +0x1F87 => 0x61, +0x1F88 => 0x41, +0x1F89 => 0x41, +0x1F8A => 0x41, +0x1F8B => 0x41, +0x1F8C => 0x41, +0x1F8D => 0x41, +0x1F8E => 0x41, +0x1F8F => 0x41, +0x1FB0 => 0x61, +0x1FB1 => 0x61, +0x1FB2 => 0x61, +0x1FB3 => 0x61, +0x1FB4 => 0x61, +0x1FB6 => 0x61, +0x1FB7 => 0x61, +0x1FB8 => 0x41, +0x1FB9 => 0x41, +0x1FBA => 0x41, +0x1FBC => 0x41, +0x1FC8 => 0x45, +0x1FD0 => 0x69, +0x1FD1 => 0x69, +0x1FD2 => 0x69, +0x1FD6 => 0x69, +0x1FD7 => 0x69, +0x1FD8 => 0x49, +0x1FD9 => 0x49, +0x1FDA => 0x49, +0x1FE8 => 0x59, +0x1FE9 => 0x59, +0x1FEA => 0x59, +0x1FF8 => 0x4F, +0x2000 => 0x20, +0x2001 => 0x20, +0x2002 => 0x20, +0x2003 => 0x20, +0x2004 => 0x20, +0x2005 => 0x20, +0x2006 => 0x20, +0x2007 => 0x20, +0x2008 => 0x20, +0x2009 => 0x20, +0x200A => 0x20, +0x202F => 0x20, +0x205F => 0x20, +0x2074 => 0x34, +0x2075 => 0x35, +0x2076 => 0x36, +0x2077 => 0x37, +0x2078 => 0x38, +0x2079 => 0x39, +0x2080 => 0x30, +0x2081 => 0x31, +0x2082 => 0x32, +0x2083 => 0x33, +0x2084 => 0x34, +0x2085 => 0x35, +0x2086 => 0x36, +0x2087 => 0x37, +0x2088 => 0x38, +0x2089 => 0x39, +0x3000 => 0x20, +]; diff --git a/vendor/opis/string/res/fold.php b/vendor/opis/string/res/fold.php new file mode 100644 index 0000000..e93f981 --- /dev/null +++ b/vendor/opis/string/res/fold.php @@ -0,0 +1,1417 @@ + 0x61, +0x42 => 0x62, +0x43 => 0x63, +0x44 => 0x64, +0x45 => 0x65, +0x46 => 0x66, +0x47 => 0x67, +0x48 => 0x68, +0x49 => 0x69, +0x4A => 0x6A, +0x4B => 0x6B, +0x4C => 0x6C, +0x4D => 0x6D, +0x4E => 0x6E, +0x4F => 0x6F, +0x50 => 0x70, +0x51 => 0x71, +0x52 => 0x72, +0x53 => 0x73, +0x54 => 0x74, +0x55 => 0x75, +0x56 => 0x76, +0x57 => 0x77, +0x58 => 0x78, +0x59 => 0x79, +0x5A => 0x7A, +0xB5 => 0x3BC, +0xC0 => 0xE0, +0xC1 => 0xE1, +0xC2 => 0xE2, +0xC3 => 0xE3, +0xC4 => 0xE4, +0xC5 => 0xE5, +0xC6 => 0xE6, +0xC7 => 0xE7, +0xC8 => 0xE8, +0xC9 => 0xE9, +0xCA => 0xEA, +0xCB => 0xEB, +0xCC => 0xEC, +0xCD => 0xED, +0xCE => 0xEE, +0xCF => 0xEF, +0xD0 => 0xF0, +0xD1 => 0xF1, +0xD2 => 0xF2, +0xD3 => 0xF3, +0xD4 => 0xF4, +0xD5 => 0xF5, +0xD6 => 0xF6, +0xD8 => 0xF8, +0xD9 => 0xF9, +0xDA => 0xFA, +0xDB => 0xFB, +0xDC => 0xFC, +0xDD => 0xFD, +0xDE => 0xFE, +0x100 => 0x101, +0x102 => 0x103, +0x104 => 0x105, +0x106 => 0x107, +0x108 => 0x109, +0x10A => 0x10B, +0x10C => 0x10D, +0x10E => 0x10F, +0x110 => 0x111, +0x112 => 0x113, +0x114 => 0x115, +0x116 => 0x117, +0x118 => 0x119, +0x11A => 0x11B, +0x11C => 0x11D, +0x11E => 0x11F, +0x120 => 0x121, +0x122 => 0x123, +0x124 => 0x125, +0x126 => 0x127, +0x128 => 0x129, +0x12A => 0x12B, +0x12C => 0x12D, +0x12E => 0x12F, +0x132 => 0x133, +0x134 => 0x135, +0x136 => 0x137, +0x139 => 0x13A, +0x13B => 0x13C, +0x13D => 0x13E, +0x13F => 0x140, +0x141 => 0x142, +0x143 => 0x144, +0x145 => 0x146, +0x147 => 0x148, +0x14A => 0x14B, +0x14C => 0x14D, +0x14E => 0x14F, +0x150 => 0x151, +0x152 => 0x153, +0x154 => 0x155, +0x156 => 0x157, +0x158 => 0x159, +0x15A => 0x15B, +0x15C => 0x15D, +0x15E => 0x15F, +0x160 => 0x161, +0x162 => 0x163, +0x164 => 0x165, +0x166 => 0x167, +0x168 => 0x169, +0x16A => 0x16B, +0x16C => 0x16D, +0x16E => 0x16F, +0x170 => 0x171, +0x172 => 0x173, +0x174 => 0x175, +0x176 => 0x177, +0x178 => 0xFF, +0x179 => 0x17A, +0x17B => 0x17C, +0x17D => 0x17E, +0x17F => 0x73, +0x181 => 0x253, +0x182 => 0x183, +0x184 => 0x185, +0x186 => 0x254, +0x187 => 0x188, +0x189 => 0x256, +0x18A => 0x257, +0x18B => 0x18C, +0x18E => 0x1DD, +0x18F => 0x259, +0x190 => 0x25B, +0x191 => 0x192, +0x193 => 0x260, +0x194 => 0x263, +0x196 => 0x269, +0x197 => 0x268, +0x198 => 0x199, +0x19C => 0x26F, +0x19D => 0x272, +0x19F => 0x275, +0x1A0 => 0x1A1, +0x1A2 => 0x1A3, +0x1A4 => 0x1A5, +0x1A6 => 0x280, +0x1A7 => 0x1A8, +0x1A9 => 0x283, +0x1AC => 0x1AD, +0x1AE => 0x288, +0x1AF => 0x1B0, +0x1B1 => 0x28A, +0x1B2 => 0x28B, +0x1B3 => 0x1B4, +0x1B5 => 0x1B6, +0x1B7 => 0x292, +0x1B8 => 0x1B9, +0x1BC => 0x1BD, +0x1C4 => 0x1C6, +0x1C5 => 0x1C6, +0x1C7 => 0x1C9, +0x1C8 => 0x1C9, +0x1CA => 0x1CC, +0x1CB => 0x1CC, +0x1CD => 0x1CE, +0x1CF => 0x1D0, +0x1D1 => 0x1D2, +0x1D3 => 0x1D4, +0x1D5 => 0x1D6, +0x1D7 => 0x1D8, +0x1D9 => 0x1DA, +0x1DB => 0x1DC, +0x1DE => 0x1DF, +0x1E0 => 0x1E1, +0x1E2 => 0x1E3, +0x1E4 => 0x1E5, +0x1E6 => 0x1E7, +0x1E8 => 0x1E9, +0x1EA => 0x1EB, +0x1EC => 0x1ED, +0x1EE => 0x1EF, +0x1F1 => 0x1F3, +0x1F2 => 0x1F3, +0x1F4 => 0x1F5, +0x1F6 => 0x195, +0x1F7 => 0x1BF, +0x1F8 => 0x1F9, +0x1FA => 0x1FB, +0x1FC => 0x1FD, +0x1FE => 0x1FF, +0x200 => 0x201, +0x202 => 0x203, +0x204 => 0x205, +0x206 => 0x207, +0x208 => 0x209, +0x20A => 0x20B, +0x20C => 0x20D, +0x20E => 0x20F, +0x210 => 0x211, +0x212 => 0x213, +0x214 => 0x215, +0x216 => 0x217, +0x218 => 0x219, +0x21A => 0x21B, +0x21C => 0x21D, +0x21E => 0x21F, +0x220 => 0x19E, +0x222 => 0x223, +0x224 => 0x225, +0x226 => 0x227, +0x228 => 0x229, +0x22A => 0x22B, +0x22C => 0x22D, +0x22E => 0x22F, +0x230 => 0x231, +0x232 => 0x233, +0x23A => 0x2C65, +0x23B => 0x23C, +0x23D => 0x19A, +0x23E => 0x2C66, +0x241 => 0x242, +0x243 => 0x180, +0x244 => 0x289, +0x245 => 0x28C, +0x246 => 0x247, +0x248 => 0x249, +0x24A => 0x24B, +0x24C => 0x24D, +0x24E => 0x24F, +0x345 => 0x3B9, +0x370 => 0x371, +0x372 => 0x373, +0x376 => 0x377, +0x37F => 0x3F3, +0x386 => 0x3AC, +0x388 => 0x3AD, +0x389 => 0x3AE, +0x38A => 0x3AF, +0x38C => 0x3CC, +0x38E => 0x3CD, +0x38F => 0x3CE, +0x391 => 0x3B1, +0x392 => 0x3B2, +0x393 => 0x3B3, +0x394 => 0x3B4, +0x395 => 0x3B5, +0x396 => 0x3B6, +0x397 => 0x3B7, +0x398 => 0x3B8, +0x399 => 0x3B9, +0x39A => 0x3BA, +0x39B => 0x3BB, +0x39C => 0x3BC, +0x39D => 0x3BD, +0x39E => 0x3BE, +0x39F => 0x3BF, +0x3A0 => 0x3C0, +0x3A1 => 0x3C1, +0x3A3 => 0x3C3, +0x3A4 => 0x3C4, +0x3A5 => 0x3C5, +0x3A6 => 0x3C6, +0x3A7 => 0x3C7, +0x3A8 => 0x3C8, +0x3A9 => 0x3C9, +0x3AA => 0x3CA, +0x3AB => 0x3CB, +0x3C2 => 0x3C3, +0x3CF => 0x3D7, +0x3D0 => 0x3B2, +0x3D1 => 0x3B8, +0x3D5 => 0x3C6, +0x3D6 => 0x3C0, +0x3D8 => 0x3D9, +0x3DA => 0x3DB, +0x3DC => 0x3DD, +0x3DE => 0x3DF, +0x3E0 => 0x3E1, +0x3E2 => 0x3E3, +0x3E4 => 0x3E5, +0x3E6 => 0x3E7, +0x3E8 => 0x3E9, +0x3EA => 0x3EB, +0x3EC => 0x3ED, +0x3EE => 0x3EF, +0x3F0 => 0x3BA, +0x3F1 => 0x3C1, +0x3F4 => 0x3B8, +0x3F5 => 0x3B5, +0x3F7 => 0x3F8, +0x3F9 => 0x3F2, +0x3FA => 0x3FB, +0x3FD => 0x37B, +0x3FE => 0x37C, +0x3FF => 0x37D, +0x400 => 0x450, +0x401 => 0x451, +0x402 => 0x452, +0x403 => 0x453, +0x404 => 0x454, +0x405 => 0x455, +0x406 => 0x456, +0x407 => 0x457, +0x408 => 0x458, +0x409 => 0x459, +0x40A => 0x45A, +0x40B => 0x45B, +0x40C => 0x45C, +0x40D => 0x45D, +0x40E => 0x45E, +0x40F => 0x45F, +0x410 => 0x430, +0x411 => 0x431, +0x412 => 0x432, +0x413 => 0x433, +0x414 => 0x434, +0x415 => 0x435, +0x416 => 0x436, +0x417 => 0x437, +0x418 => 0x438, +0x419 => 0x439, +0x41A => 0x43A, +0x41B => 0x43B, +0x41C => 0x43C, +0x41D => 0x43D, +0x41E => 0x43E, +0x41F => 0x43F, +0x420 => 0x440, +0x421 => 0x441, +0x422 => 0x442, +0x423 => 0x443, +0x424 => 0x444, +0x425 => 0x445, +0x426 => 0x446, +0x427 => 0x447, +0x428 => 0x448, +0x429 => 0x449, +0x42A => 0x44A, +0x42B => 0x44B, +0x42C => 0x44C, +0x42D => 0x44D, +0x42E => 0x44E, +0x42F => 0x44F, +0x460 => 0x461, +0x462 => 0x463, +0x464 => 0x465, +0x466 => 0x467, +0x468 => 0x469, +0x46A => 0x46B, +0x46C => 0x46D, +0x46E => 0x46F, +0x470 => 0x471, +0x472 => 0x473, +0x474 => 0x475, +0x476 => 0x477, +0x478 => 0x479, +0x47A => 0x47B, +0x47C => 0x47D, +0x47E => 0x47F, +0x480 => 0x481, +0x48A => 0x48B, +0x48C => 0x48D, +0x48E => 0x48F, +0x490 => 0x491, +0x492 => 0x493, +0x494 => 0x495, +0x496 => 0x497, +0x498 => 0x499, +0x49A => 0x49B, +0x49C => 0x49D, +0x49E => 0x49F, +0x4A0 => 0x4A1, +0x4A2 => 0x4A3, +0x4A4 => 0x4A5, +0x4A6 => 0x4A7, +0x4A8 => 0x4A9, +0x4AA => 0x4AB, +0x4AC => 0x4AD, +0x4AE => 0x4AF, +0x4B0 => 0x4B1, +0x4B2 => 0x4B3, +0x4B4 => 0x4B5, +0x4B6 => 0x4B7, +0x4B8 => 0x4B9, +0x4BA => 0x4BB, +0x4BC => 0x4BD, +0x4BE => 0x4BF, +0x4C0 => 0x4CF, +0x4C1 => 0x4C2, +0x4C3 => 0x4C4, +0x4C5 => 0x4C6, +0x4C7 => 0x4C8, +0x4C9 => 0x4CA, +0x4CB => 0x4CC, +0x4CD => 0x4CE, +0x4D0 => 0x4D1, +0x4D2 => 0x4D3, +0x4D4 => 0x4D5, +0x4D6 => 0x4D7, +0x4D8 => 0x4D9, +0x4DA => 0x4DB, +0x4DC => 0x4DD, +0x4DE => 0x4DF, +0x4E0 => 0x4E1, +0x4E2 => 0x4E3, +0x4E4 => 0x4E5, +0x4E6 => 0x4E7, +0x4E8 => 0x4E9, +0x4EA => 0x4EB, +0x4EC => 0x4ED, +0x4EE => 0x4EF, +0x4F0 => 0x4F1, +0x4F2 => 0x4F3, +0x4F4 => 0x4F5, +0x4F6 => 0x4F7, +0x4F8 => 0x4F9, +0x4FA => 0x4FB, +0x4FC => 0x4FD, +0x4FE => 0x4FF, +0x500 => 0x501, +0x502 => 0x503, +0x504 => 0x505, +0x506 => 0x507, +0x508 => 0x509, +0x50A => 0x50B, +0x50C => 0x50D, +0x50E => 0x50F, +0x510 => 0x511, +0x512 => 0x513, +0x514 => 0x515, +0x516 => 0x517, +0x518 => 0x519, +0x51A => 0x51B, +0x51C => 0x51D, +0x51E => 0x51F, +0x520 => 0x521, +0x522 => 0x523, +0x524 => 0x525, +0x526 => 0x527, +0x528 => 0x529, +0x52A => 0x52B, +0x52C => 0x52D, +0x52E => 0x52F, +0x531 => 0x561, +0x532 => 0x562, +0x533 => 0x563, +0x534 => 0x564, +0x535 => 0x565, +0x536 => 0x566, +0x537 => 0x567, +0x538 => 0x568, +0x539 => 0x569, +0x53A => 0x56A, +0x53B => 0x56B, +0x53C => 0x56C, +0x53D => 0x56D, +0x53E => 0x56E, +0x53F => 0x56F, +0x540 => 0x570, +0x541 => 0x571, +0x542 => 0x572, +0x543 => 0x573, +0x544 => 0x574, +0x545 => 0x575, +0x546 => 0x576, +0x547 => 0x577, +0x548 => 0x578, +0x549 => 0x579, +0x54A => 0x57A, +0x54B => 0x57B, +0x54C => 0x57C, +0x54D => 0x57D, +0x54E => 0x57E, +0x54F => 0x57F, +0x550 => 0x580, +0x551 => 0x581, +0x552 => 0x582, +0x553 => 0x583, +0x554 => 0x584, +0x555 => 0x585, +0x556 => 0x586, +0x10A0 => 0x2D00, +0x10A1 => 0x2D01, +0x10A2 => 0x2D02, +0x10A3 => 0x2D03, +0x10A4 => 0x2D04, +0x10A5 => 0x2D05, +0x10A6 => 0x2D06, +0x10A7 => 0x2D07, +0x10A8 => 0x2D08, +0x10A9 => 0x2D09, +0x10AA => 0x2D0A, +0x10AB => 0x2D0B, +0x10AC => 0x2D0C, +0x10AD => 0x2D0D, +0x10AE => 0x2D0E, +0x10AF => 0x2D0F, +0x10B0 => 0x2D10, +0x10B1 => 0x2D11, +0x10B2 => 0x2D12, +0x10B3 => 0x2D13, +0x10B4 => 0x2D14, +0x10B5 => 0x2D15, +0x10B6 => 0x2D16, +0x10B7 => 0x2D17, +0x10B8 => 0x2D18, +0x10B9 => 0x2D19, +0x10BA => 0x2D1A, +0x10BB => 0x2D1B, +0x10BC => 0x2D1C, +0x10BD => 0x2D1D, +0x10BE => 0x2D1E, +0x10BF => 0x2D1F, +0x10C0 => 0x2D20, +0x10C1 => 0x2D21, +0x10C2 => 0x2D22, +0x10C3 => 0x2D23, +0x10C4 => 0x2D24, +0x10C5 => 0x2D25, +0x10C7 => 0x2D27, +0x10CD => 0x2D2D, +0x13F8 => 0x13F0, +0x13F9 => 0x13F1, +0x13FA => 0x13F2, +0x13FB => 0x13F3, +0x13FC => 0x13F4, +0x13FD => 0x13F5, +0x1C80 => 0x432, +0x1C81 => 0x434, +0x1C82 => 0x43E, +0x1C83 => 0x441, +0x1C84 => 0x442, +0x1C85 => 0x442, +0x1C86 => 0x44A, +0x1C87 => 0x463, +0x1C88 => 0xA64B, +0x1C90 => 0x10D0, +0x1C91 => 0x10D1, +0x1C92 => 0x10D2, +0x1C93 => 0x10D3, +0x1C94 => 0x10D4, +0x1C95 => 0x10D5, +0x1C96 => 0x10D6, +0x1C97 => 0x10D7, +0x1C98 => 0x10D8, +0x1C99 => 0x10D9, +0x1C9A => 0x10DA, +0x1C9B => 0x10DB, +0x1C9C => 0x10DC, +0x1C9D => 0x10DD, +0x1C9E => 0x10DE, +0x1C9F => 0x10DF, +0x1CA0 => 0x10E0, +0x1CA1 => 0x10E1, +0x1CA2 => 0x10E2, +0x1CA3 => 0x10E3, +0x1CA4 => 0x10E4, +0x1CA5 => 0x10E5, +0x1CA6 => 0x10E6, +0x1CA7 => 0x10E7, +0x1CA8 => 0x10E8, +0x1CA9 => 0x10E9, +0x1CAA => 0x10EA, +0x1CAB => 0x10EB, +0x1CAC => 0x10EC, +0x1CAD => 0x10ED, +0x1CAE => 0x10EE, +0x1CAF => 0x10EF, +0x1CB0 => 0x10F0, +0x1CB1 => 0x10F1, +0x1CB2 => 0x10F2, +0x1CB3 => 0x10F3, +0x1CB4 => 0x10F4, +0x1CB5 => 0x10F5, +0x1CB6 => 0x10F6, +0x1CB7 => 0x10F7, +0x1CB8 => 0x10F8, +0x1CB9 => 0x10F9, +0x1CBA => 0x10FA, +0x1CBD => 0x10FD, +0x1CBE => 0x10FE, +0x1CBF => 0x10FF, +0x1E00 => 0x1E01, +0x1E02 => 0x1E03, +0x1E04 => 0x1E05, +0x1E06 => 0x1E07, +0x1E08 => 0x1E09, +0x1E0A => 0x1E0B, +0x1E0C => 0x1E0D, +0x1E0E => 0x1E0F, +0x1E10 => 0x1E11, +0x1E12 => 0x1E13, +0x1E14 => 0x1E15, +0x1E16 => 0x1E17, +0x1E18 => 0x1E19, +0x1E1A => 0x1E1B, +0x1E1C => 0x1E1D, +0x1E1E => 0x1E1F, +0x1E20 => 0x1E21, +0x1E22 => 0x1E23, +0x1E24 => 0x1E25, +0x1E26 => 0x1E27, +0x1E28 => 0x1E29, +0x1E2A => 0x1E2B, +0x1E2C => 0x1E2D, +0x1E2E => 0x1E2F, +0x1E30 => 0x1E31, +0x1E32 => 0x1E33, +0x1E34 => 0x1E35, +0x1E36 => 0x1E37, +0x1E38 => 0x1E39, +0x1E3A => 0x1E3B, +0x1E3C => 0x1E3D, +0x1E3E => 0x1E3F, +0x1E40 => 0x1E41, +0x1E42 => 0x1E43, +0x1E44 => 0x1E45, +0x1E46 => 0x1E47, +0x1E48 => 0x1E49, +0x1E4A => 0x1E4B, +0x1E4C => 0x1E4D, +0x1E4E => 0x1E4F, +0x1E50 => 0x1E51, +0x1E52 => 0x1E53, +0x1E54 => 0x1E55, +0x1E56 => 0x1E57, +0x1E58 => 0x1E59, +0x1E5A => 0x1E5B, +0x1E5C => 0x1E5D, +0x1E5E => 0x1E5F, +0x1E60 => 0x1E61, +0x1E62 => 0x1E63, +0x1E64 => 0x1E65, +0x1E66 => 0x1E67, +0x1E68 => 0x1E69, +0x1E6A => 0x1E6B, +0x1E6C => 0x1E6D, +0x1E6E => 0x1E6F, +0x1E70 => 0x1E71, +0x1E72 => 0x1E73, +0x1E74 => 0x1E75, +0x1E76 => 0x1E77, +0x1E78 => 0x1E79, +0x1E7A => 0x1E7B, +0x1E7C => 0x1E7D, +0x1E7E => 0x1E7F, +0x1E80 => 0x1E81, +0x1E82 => 0x1E83, +0x1E84 => 0x1E85, +0x1E86 => 0x1E87, +0x1E88 => 0x1E89, +0x1E8A => 0x1E8B, +0x1E8C => 0x1E8D, +0x1E8E => 0x1E8F, +0x1E90 => 0x1E91, +0x1E92 => 0x1E93, +0x1E94 => 0x1E95, +0x1E9B => 0x1E61, +0x1E9E => 0xDF, +0x1EA0 => 0x1EA1, +0x1EA2 => 0x1EA3, +0x1EA4 => 0x1EA5, +0x1EA6 => 0x1EA7, +0x1EA8 => 0x1EA9, +0x1EAA => 0x1EAB, +0x1EAC => 0x1EAD, +0x1EAE => 0x1EAF, +0x1EB0 => 0x1EB1, +0x1EB2 => 0x1EB3, +0x1EB4 => 0x1EB5, +0x1EB6 => 0x1EB7, +0x1EB8 => 0x1EB9, +0x1EBA => 0x1EBB, +0x1EBC => 0x1EBD, +0x1EBE => 0x1EBF, +0x1EC0 => 0x1EC1, +0x1EC2 => 0x1EC3, +0x1EC4 => 0x1EC5, +0x1EC6 => 0x1EC7, +0x1EC8 => 0x1EC9, +0x1ECA => 0x1ECB, +0x1ECC => 0x1ECD, +0x1ECE => 0x1ECF, +0x1ED0 => 0x1ED1, +0x1ED2 => 0x1ED3, +0x1ED4 => 0x1ED5, +0x1ED6 => 0x1ED7, +0x1ED8 => 0x1ED9, +0x1EDA => 0x1EDB, +0x1EDC => 0x1EDD, +0x1EDE => 0x1EDF, +0x1EE0 => 0x1EE1, +0x1EE2 => 0x1EE3, +0x1EE4 => 0x1EE5, +0x1EE6 => 0x1EE7, +0x1EE8 => 0x1EE9, +0x1EEA => 0x1EEB, +0x1EEC => 0x1EED, +0x1EEE => 0x1EEF, +0x1EF0 => 0x1EF1, +0x1EF2 => 0x1EF3, +0x1EF4 => 0x1EF5, +0x1EF6 => 0x1EF7, +0x1EF8 => 0x1EF9, +0x1EFA => 0x1EFB, +0x1EFC => 0x1EFD, +0x1EFE => 0x1EFF, +0x1F08 => 0x1F00, +0x1F09 => 0x1F01, +0x1F0A => 0x1F02, +0x1F0B => 0x1F03, +0x1F0C => 0x1F04, +0x1F0D => 0x1F05, +0x1F0E => 0x1F06, +0x1F0F => 0x1F07, +0x1F18 => 0x1F10, +0x1F19 => 0x1F11, +0x1F1A => 0x1F12, +0x1F1B => 0x1F13, +0x1F1C => 0x1F14, +0x1F1D => 0x1F15, +0x1F28 => 0x1F20, +0x1F29 => 0x1F21, +0x1F2A => 0x1F22, +0x1F2B => 0x1F23, +0x1F2C => 0x1F24, +0x1F2D => 0x1F25, +0x1F2E => 0x1F26, +0x1F2F => 0x1F27, +0x1F38 => 0x1F30, +0x1F39 => 0x1F31, +0x1F3A => 0x1F32, +0x1F3B => 0x1F33, +0x1F3C => 0x1F34, +0x1F3D => 0x1F35, +0x1F3E => 0x1F36, +0x1F3F => 0x1F37, +0x1F48 => 0x1F40, +0x1F49 => 0x1F41, +0x1F4A => 0x1F42, +0x1F4B => 0x1F43, +0x1F4C => 0x1F44, +0x1F4D => 0x1F45, +0x1F59 => 0x1F51, +0x1F5B => 0x1F53, +0x1F5D => 0x1F55, +0x1F5F => 0x1F57, +0x1F68 => 0x1F60, +0x1F69 => 0x1F61, +0x1F6A => 0x1F62, +0x1F6B => 0x1F63, +0x1F6C => 0x1F64, +0x1F6D => 0x1F65, +0x1F6E => 0x1F66, +0x1F6F => 0x1F67, +0x1F88 => 0x1F80, +0x1F89 => 0x1F81, +0x1F8A => 0x1F82, +0x1F8B => 0x1F83, +0x1F8C => 0x1F84, +0x1F8D => 0x1F85, +0x1F8E => 0x1F86, +0x1F8F => 0x1F87, +0x1F98 => 0x1F90, +0x1F99 => 0x1F91, +0x1F9A => 0x1F92, +0x1F9B => 0x1F93, +0x1F9C => 0x1F94, +0x1F9D => 0x1F95, +0x1F9E => 0x1F96, +0x1F9F => 0x1F97, +0x1FA8 => 0x1FA0, +0x1FA9 => 0x1FA1, +0x1FAA => 0x1FA2, +0x1FAB => 0x1FA3, +0x1FAC => 0x1FA4, +0x1FAD => 0x1FA5, +0x1FAE => 0x1FA6, +0x1FAF => 0x1FA7, +0x1FB8 => 0x1FB0, +0x1FB9 => 0x1FB1, +0x1FBA => 0x1F70, +0x1FBB => 0x1F71, +0x1FBC => 0x1FB3, +0x1FBE => 0x3B9, +0x1FC8 => 0x1F72, +0x1FC9 => 0x1F73, +0x1FCA => 0x1F74, +0x1FCB => 0x1F75, +0x1FCC => 0x1FC3, +0x1FD8 => 0x1FD0, +0x1FD9 => 0x1FD1, +0x1FDA => 0x1F76, +0x1FDB => 0x1F77, +0x1FE8 => 0x1FE0, +0x1FE9 => 0x1FE1, +0x1FEA => 0x1F7A, +0x1FEB => 0x1F7B, +0x1FEC => 0x1FE5, +0x1FF8 => 0x1F78, +0x1FF9 => 0x1F79, +0x1FFA => 0x1F7C, +0x1FFB => 0x1F7D, +0x1FFC => 0x1FF3, +0x2126 => 0x3C9, +0x212A => 0x6B, +0x212B => 0xE5, +0x2132 => 0x214E, +0x2160 => 0x2170, +0x2161 => 0x2171, +0x2162 => 0x2172, +0x2163 => 0x2173, +0x2164 => 0x2174, +0x2165 => 0x2175, +0x2166 => 0x2176, +0x2167 => 0x2177, +0x2168 => 0x2178, +0x2169 => 0x2179, +0x216A => 0x217A, +0x216B => 0x217B, +0x216C => 0x217C, +0x216D => 0x217D, +0x216E => 0x217E, +0x216F => 0x217F, +0x2183 => 0x2184, +0x24B6 => 0x24D0, +0x24B7 => 0x24D1, +0x24B8 => 0x24D2, +0x24B9 => 0x24D3, +0x24BA => 0x24D4, +0x24BB => 0x24D5, +0x24BC => 0x24D6, +0x24BD => 0x24D7, +0x24BE => 0x24D8, +0x24BF => 0x24D9, +0x24C0 => 0x24DA, +0x24C1 => 0x24DB, +0x24C2 => 0x24DC, +0x24C3 => 0x24DD, +0x24C4 => 0x24DE, +0x24C5 => 0x24DF, +0x24C6 => 0x24E0, +0x24C7 => 0x24E1, +0x24C8 => 0x24E2, +0x24C9 => 0x24E3, +0x24CA => 0x24E4, +0x24CB => 0x24E5, +0x24CC => 0x24E6, +0x24CD => 0x24E7, +0x24CE => 0x24E8, +0x24CF => 0x24E9, +0x2C00 => 0x2C30, +0x2C01 => 0x2C31, +0x2C02 => 0x2C32, +0x2C03 => 0x2C33, +0x2C04 => 0x2C34, +0x2C05 => 0x2C35, +0x2C06 => 0x2C36, +0x2C07 => 0x2C37, +0x2C08 => 0x2C38, +0x2C09 => 0x2C39, +0x2C0A => 0x2C3A, +0x2C0B => 0x2C3B, +0x2C0C => 0x2C3C, +0x2C0D => 0x2C3D, +0x2C0E => 0x2C3E, +0x2C0F => 0x2C3F, +0x2C10 => 0x2C40, +0x2C11 => 0x2C41, +0x2C12 => 0x2C42, +0x2C13 => 0x2C43, +0x2C14 => 0x2C44, +0x2C15 => 0x2C45, +0x2C16 => 0x2C46, +0x2C17 => 0x2C47, +0x2C18 => 0x2C48, +0x2C19 => 0x2C49, +0x2C1A => 0x2C4A, +0x2C1B => 0x2C4B, +0x2C1C => 0x2C4C, +0x2C1D => 0x2C4D, +0x2C1E => 0x2C4E, +0x2C1F => 0x2C4F, +0x2C20 => 0x2C50, +0x2C21 => 0x2C51, +0x2C22 => 0x2C52, +0x2C23 => 0x2C53, +0x2C24 => 0x2C54, +0x2C25 => 0x2C55, +0x2C26 => 0x2C56, +0x2C27 => 0x2C57, +0x2C28 => 0x2C58, +0x2C29 => 0x2C59, +0x2C2A => 0x2C5A, +0x2C2B => 0x2C5B, +0x2C2C => 0x2C5C, +0x2C2D => 0x2C5D, +0x2C2E => 0x2C5E, +0x2C60 => 0x2C61, +0x2C62 => 0x26B, +0x2C63 => 0x1D7D, +0x2C64 => 0x27D, +0x2C67 => 0x2C68, +0x2C69 => 0x2C6A, +0x2C6B => 0x2C6C, +0x2C6D => 0x251, +0x2C6E => 0x271, +0x2C6F => 0x250, +0x2C70 => 0x252, +0x2C72 => 0x2C73, +0x2C75 => 0x2C76, +0x2C7E => 0x23F, +0x2C7F => 0x240, +0x2C80 => 0x2C81, +0x2C82 => 0x2C83, +0x2C84 => 0x2C85, +0x2C86 => 0x2C87, +0x2C88 => 0x2C89, +0x2C8A => 0x2C8B, +0x2C8C => 0x2C8D, +0x2C8E => 0x2C8F, +0x2C90 => 0x2C91, +0x2C92 => 0x2C93, +0x2C94 => 0x2C95, +0x2C96 => 0x2C97, +0x2C98 => 0x2C99, +0x2C9A => 0x2C9B, +0x2C9C => 0x2C9D, +0x2C9E => 0x2C9F, +0x2CA0 => 0x2CA1, +0x2CA2 => 0x2CA3, +0x2CA4 => 0x2CA5, +0x2CA6 => 0x2CA7, +0x2CA8 => 0x2CA9, +0x2CAA => 0x2CAB, +0x2CAC => 0x2CAD, +0x2CAE => 0x2CAF, +0x2CB0 => 0x2CB1, +0x2CB2 => 0x2CB3, +0x2CB4 => 0x2CB5, +0x2CB6 => 0x2CB7, +0x2CB8 => 0x2CB9, +0x2CBA => 0x2CBB, +0x2CBC => 0x2CBD, +0x2CBE => 0x2CBF, +0x2CC0 => 0x2CC1, +0x2CC2 => 0x2CC3, +0x2CC4 => 0x2CC5, +0x2CC6 => 0x2CC7, +0x2CC8 => 0x2CC9, +0x2CCA => 0x2CCB, +0x2CCC => 0x2CCD, +0x2CCE => 0x2CCF, +0x2CD0 => 0x2CD1, +0x2CD2 => 0x2CD3, +0x2CD4 => 0x2CD5, +0x2CD6 => 0x2CD7, +0x2CD8 => 0x2CD9, +0x2CDA => 0x2CDB, +0x2CDC => 0x2CDD, +0x2CDE => 0x2CDF, +0x2CE0 => 0x2CE1, +0x2CE2 => 0x2CE3, +0x2CEB => 0x2CEC, +0x2CED => 0x2CEE, +0x2CF2 => 0x2CF3, +0xA640 => 0xA641, +0xA642 => 0xA643, +0xA644 => 0xA645, +0xA646 => 0xA647, +0xA648 => 0xA649, +0xA64A => 0xA64B, +0xA64C => 0xA64D, +0xA64E => 0xA64F, +0xA650 => 0xA651, +0xA652 => 0xA653, +0xA654 => 0xA655, +0xA656 => 0xA657, +0xA658 => 0xA659, +0xA65A => 0xA65B, +0xA65C => 0xA65D, +0xA65E => 0xA65F, +0xA660 => 0xA661, +0xA662 => 0xA663, +0xA664 => 0xA665, +0xA666 => 0xA667, +0xA668 => 0xA669, +0xA66A => 0xA66B, +0xA66C => 0xA66D, +0xA680 => 0xA681, +0xA682 => 0xA683, +0xA684 => 0xA685, +0xA686 => 0xA687, +0xA688 => 0xA689, +0xA68A => 0xA68B, +0xA68C => 0xA68D, +0xA68E => 0xA68F, +0xA690 => 0xA691, +0xA692 => 0xA693, +0xA694 => 0xA695, +0xA696 => 0xA697, +0xA698 => 0xA699, +0xA69A => 0xA69B, +0xA722 => 0xA723, +0xA724 => 0xA725, +0xA726 => 0xA727, +0xA728 => 0xA729, +0xA72A => 0xA72B, +0xA72C => 0xA72D, +0xA72E => 0xA72F, +0xA732 => 0xA733, +0xA734 => 0xA735, +0xA736 => 0xA737, +0xA738 => 0xA739, +0xA73A => 0xA73B, +0xA73C => 0xA73D, +0xA73E => 0xA73F, +0xA740 => 0xA741, +0xA742 => 0xA743, +0xA744 => 0xA745, +0xA746 => 0xA747, +0xA748 => 0xA749, +0xA74A => 0xA74B, +0xA74C => 0xA74D, +0xA74E => 0xA74F, +0xA750 => 0xA751, +0xA752 => 0xA753, +0xA754 => 0xA755, +0xA756 => 0xA757, +0xA758 => 0xA759, +0xA75A => 0xA75B, +0xA75C => 0xA75D, +0xA75E => 0xA75F, +0xA760 => 0xA761, +0xA762 => 0xA763, +0xA764 => 0xA765, +0xA766 => 0xA767, +0xA768 => 0xA769, +0xA76A => 0xA76B, +0xA76C => 0xA76D, +0xA76E => 0xA76F, +0xA779 => 0xA77A, +0xA77B => 0xA77C, +0xA77D => 0x1D79, +0xA77E => 0xA77F, +0xA780 => 0xA781, +0xA782 => 0xA783, +0xA784 => 0xA785, +0xA786 => 0xA787, +0xA78B => 0xA78C, +0xA78D => 0x265, +0xA790 => 0xA791, +0xA792 => 0xA793, +0xA796 => 0xA797, +0xA798 => 0xA799, +0xA79A => 0xA79B, +0xA79C => 0xA79D, +0xA79E => 0xA79F, +0xA7A0 => 0xA7A1, +0xA7A2 => 0xA7A3, +0xA7A4 => 0xA7A5, +0xA7A6 => 0xA7A7, +0xA7A8 => 0xA7A9, +0xA7AA => 0x266, +0xA7AB => 0x25C, +0xA7AC => 0x261, +0xA7AD => 0x26C, +0xA7AE => 0x26A, +0xA7B0 => 0x29E, +0xA7B1 => 0x287, +0xA7B2 => 0x29D, +0xA7B3 => 0xAB53, +0xA7B4 => 0xA7B5, +0xA7B6 => 0xA7B7, +0xA7B8 => 0xA7B9, +0xA7BA => 0xA7BB, +0xA7BC => 0xA7BD, +0xA7BE => 0xA7BF, +0xA7C2 => 0xA7C3, +0xA7C4 => 0xA794, +0xA7C5 => 0x282, +0xA7C6 => 0x1D8E, +0xA7C7 => 0xA7C8, +0xA7C9 => 0xA7CA, +0xA7F5 => 0xA7F6, +0xAB70 => 0x13A0, +0xAB71 => 0x13A1, +0xAB72 => 0x13A2, +0xAB73 => 0x13A3, +0xAB74 => 0x13A4, +0xAB75 => 0x13A5, +0xAB76 => 0x13A6, +0xAB77 => 0x13A7, +0xAB78 => 0x13A8, +0xAB79 => 0x13A9, +0xAB7A => 0x13AA, +0xAB7B => 0x13AB, +0xAB7C => 0x13AC, +0xAB7D => 0x13AD, +0xAB7E => 0x13AE, +0xAB7F => 0x13AF, +0xAB80 => 0x13B0, +0xAB81 => 0x13B1, +0xAB82 => 0x13B2, +0xAB83 => 0x13B3, +0xAB84 => 0x13B4, +0xAB85 => 0x13B5, +0xAB86 => 0x13B6, +0xAB87 => 0x13B7, +0xAB88 => 0x13B8, +0xAB89 => 0x13B9, +0xAB8A => 0x13BA, +0xAB8B => 0x13BB, +0xAB8C => 0x13BC, +0xAB8D => 0x13BD, +0xAB8E => 0x13BE, +0xAB8F => 0x13BF, +0xAB90 => 0x13C0, +0xAB91 => 0x13C1, +0xAB92 => 0x13C2, +0xAB93 => 0x13C3, +0xAB94 => 0x13C4, +0xAB95 => 0x13C5, +0xAB96 => 0x13C6, +0xAB97 => 0x13C7, +0xAB98 => 0x13C8, +0xAB99 => 0x13C9, +0xAB9A => 0x13CA, +0xAB9B => 0x13CB, +0xAB9C => 0x13CC, +0xAB9D => 0x13CD, +0xAB9E => 0x13CE, +0xAB9F => 0x13CF, +0xABA0 => 0x13D0, +0xABA1 => 0x13D1, +0xABA2 => 0x13D2, +0xABA3 => 0x13D3, +0xABA4 => 0x13D4, +0xABA5 => 0x13D5, +0xABA6 => 0x13D6, +0xABA7 => 0x13D7, +0xABA8 => 0x13D8, +0xABA9 => 0x13D9, +0xABAA => 0x13DA, +0xABAB => 0x13DB, +0xABAC => 0x13DC, +0xABAD => 0x13DD, +0xABAE => 0x13DE, +0xABAF => 0x13DF, +0xABB0 => 0x13E0, +0xABB1 => 0x13E1, +0xABB2 => 0x13E2, +0xABB3 => 0x13E3, +0xABB4 => 0x13E4, +0xABB5 => 0x13E5, +0xABB6 => 0x13E6, +0xABB7 => 0x13E7, +0xABB8 => 0x13E8, +0xABB9 => 0x13E9, +0xABBA => 0x13EA, +0xABBB => 0x13EB, +0xABBC => 0x13EC, +0xABBD => 0x13ED, +0xABBE => 0x13EE, +0xABBF => 0x13EF, +0xFF21 => 0xFF41, +0xFF22 => 0xFF42, +0xFF23 => 0xFF43, +0xFF24 => 0xFF44, +0xFF25 => 0xFF45, +0xFF26 => 0xFF46, +0xFF27 => 0xFF47, +0xFF28 => 0xFF48, +0xFF29 => 0xFF49, +0xFF2A => 0xFF4A, +0xFF2B => 0xFF4B, +0xFF2C => 0xFF4C, +0xFF2D => 0xFF4D, +0xFF2E => 0xFF4E, +0xFF2F => 0xFF4F, +0xFF30 => 0xFF50, +0xFF31 => 0xFF51, +0xFF32 => 0xFF52, +0xFF33 => 0xFF53, +0xFF34 => 0xFF54, +0xFF35 => 0xFF55, +0xFF36 => 0xFF56, +0xFF37 => 0xFF57, +0xFF38 => 0xFF58, +0xFF39 => 0xFF59, +0xFF3A => 0xFF5A, +0x10400 => 0x10428, +0x10401 => 0x10429, +0x10402 => 0x1042A, +0x10403 => 0x1042B, +0x10404 => 0x1042C, +0x10405 => 0x1042D, +0x10406 => 0x1042E, +0x10407 => 0x1042F, +0x10408 => 0x10430, +0x10409 => 0x10431, +0x1040A => 0x10432, +0x1040B => 0x10433, +0x1040C => 0x10434, +0x1040D => 0x10435, +0x1040E => 0x10436, +0x1040F => 0x10437, +0x10410 => 0x10438, +0x10411 => 0x10439, +0x10412 => 0x1043A, +0x10413 => 0x1043B, +0x10414 => 0x1043C, +0x10415 => 0x1043D, +0x10416 => 0x1043E, +0x10417 => 0x1043F, +0x10418 => 0x10440, +0x10419 => 0x10441, +0x1041A => 0x10442, +0x1041B => 0x10443, +0x1041C => 0x10444, +0x1041D => 0x10445, +0x1041E => 0x10446, +0x1041F => 0x10447, +0x10420 => 0x10448, +0x10421 => 0x10449, +0x10422 => 0x1044A, +0x10423 => 0x1044B, +0x10424 => 0x1044C, +0x10425 => 0x1044D, +0x10426 => 0x1044E, +0x10427 => 0x1044F, +0x104B0 => 0x104D8, +0x104B1 => 0x104D9, +0x104B2 => 0x104DA, +0x104B3 => 0x104DB, +0x104B4 => 0x104DC, +0x104B5 => 0x104DD, +0x104B6 => 0x104DE, +0x104B7 => 0x104DF, +0x104B8 => 0x104E0, +0x104B9 => 0x104E1, +0x104BA => 0x104E2, +0x104BB => 0x104E3, +0x104BC => 0x104E4, +0x104BD => 0x104E5, +0x104BE => 0x104E6, +0x104BF => 0x104E7, +0x104C0 => 0x104E8, +0x104C1 => 0x104E9, +0x104C2 => 0x104EA, +0x104C3 => 0x104EB, +0x104C4 => 0x104EC, +0x104C5 => 0x104ED, +0x104C6 => 0x104EE, +0x104C7 => 0x104EF, +0x104C8 => 0x104F0, +0x104C9 => 0x104F1, +0x104CA => 0x104F2, +0x104CB => 0x104F3, +0x104CC => 0x104F4, +0x104CD => 0x104F5, +0x104CE => 0x104F6, +0x104CF => 0x104F7, +0x104D0 => 0x104F8, +0x104D1 => 0x104F9, +0x104D2 => 0x104FA, +0x104D3 => 0x104FB, +0x10C80 => 0x10CC0, +0x10C81 => 0x10CC1, +0x10C82 => 0x10CC2, +0x10C83 => 0x10CC3, +0x10C84 => 0x10CC4, +0x10C85 => 0x10CC5, +0x10C86 => 0x10CC6, +0x10C87 => 0x10CC7, +0x10C88 => 0x10CC8, +0x10C89 => 0x10CC9, +0x10C8A => 0x10CCA, +0x10C8B => 0x10CCB, +0x10C8C => 0x10CCC, +0x10C8D => 0x10CCD, +0x10C8E => 0x10CCE, +0x10C8F => 0x10CCF, +0x10C90 => 0x10CD0, +0x10C91 => 0x10CD1, +0x10C92 => 0x10CD2, +0x10C93 => 0x10CD3, +0x10C94 => 0x10CD4, +0x10C95 => 0x10CD5, +0x10C96 => 0x10CD6, +0x10C97 => 0x10CD7, +0x10C98 => 0x10CD8, +0x10C99 => 0x10CD9, +0x10C9A => 0x10CDA, +0x10C9B => 0x10CDB, +0x10C9C => 0x10CDC, +0x10C9D => 0x10CDD, +0x10C9E => 0x10CDE, +0x10C9F => 0x10CDF, +0x10CA0 => 0x10CE0, +0x10CA1 => 0x10CE1, +0x10CA2 => 0x10CE2, +0x10CA3 => 0x10CE3, +0x10CA4 => 0x10CE4, +0x10CA5 => 0x10CE5, +0x10CA6 => 0x10CE6, +0x10CA7 => 0x10CE7, +0x10CA8 => 0x10CE8, +0x10CA9 => 0x10CE9, +0x10CAA => 0x10CEA, +0x10CAB => 0x10CEB, +0x10CAC => 0x10CEC, +0x10CAD => 0x10CED, +0x10CAE => 0x10CEE, +0x10CAF => 0x10CEF, +0x10CB0 => 0x10CF0, +0x10CB1 => 0x10CF1, +0x10CB2 => 0x10CF2, +0x118A0 => 0x118C0, +0x118A1 => 0x118C1, +0x118A2 => 0x118C2, +0x118A3 => 0x118C3, +0x118A4 => 0x118C4, +0x118A5 => 0x118C5, +0x118A6 => 0x118C6, +0x118A7 => 0x118C7, +0x118A8 => 0x118C8, +0x118A9 => 0x118C9, +0x118AA => 0x118CA, +0x118AB => 0x118CB, +0x118AC => 0x118CC, +0x118AD => 0x118CD, +0x118AE => 0x118CE, +0x118AF => 0x118CF, +0x118B0 => 0x118D0, +0x118B1 => 0x118D1, +0x118B2 => 0x118D2, +0x118B3 => 0x118D3, +0x118B4 => 0x118D4, +0x118B5 => 0x118D5, +0x118B6 => 0x118D6, +0x118B7 => 0x118D7, +0x118B8 => 0x118D8, +0x118B9 => 0x118D9, +0x118BA => 0x118DA, +0x118BB => 0x118DB, +0x118BC => 0x118DC, +0x118BD => 0x118DD, +0x118BE => 0x118DE, +0x118BF => 0x118DF, +0x16E40 => 0x16E60, +0x16E41 => 0x16E61, +0x16E42 => 0x16E62, +0x16E43 => 0x16E63, +0x16E44 => 0x16E64, +0x16E45 => 0x16E65, +0x16E46 => 0x16E66, +0x16E47 => 0x16E67, +0x16E48 => 0x16E68, +0x16E49 => 0x16E69, +0x16E4A => 0x16E6A, +0x16E4B => 0x16E6B, +0x16E4C => 0x16E6C, +0x16E4D => 0x16E6D, +0x16E4E => 0x16E6E, +0x16E4F => 0x16E6F, +0x16E50 => 0x16E70, +0x16E51 => 0x16E71, +0x16E52 => 0x16E72, +0x16E53 => 0x16E73, +0x16E54 => 0x16E74, +0x16E55 => 0x16E75, +0x16E56 => 0x16E76, +0x16E57 => 0x16E77, +0x16E58 => 0x16E78, +0x16E59 => 0x16E79, +0x16E5A => 0x16E7A, +0x16E5B => 0x16E7B, +0x16E5C => 0x16E7C, +0x16E5D => 0x16E7D, +0x16E5E => 0x16E7E, +0x16E5F => 0x16E7F, +0x1E900 => 0x1E922, +0x1E901 => 0x1E923, +0x1E902 => 0x1E924, +0x1E903 => 0x1E925, +0x1E904 => 0x1E926, +0x1E905 => 0x1E927, +0x1E906 => 0x1E928, +0x1E907 => 0x1E929, +0x1E908 => 0x1E92A, +0x1E909 => 0x1E92B, +0x1E90A => 0x1E92C, +0x1E90B => 0x1E92D, +0x1E90C => 0x1E92E, +0x1E90D => 0x1E92F, +0x1E90E => 0x1E930, +0x1E90F => 0x1E931, +0x1E910 => 0x1E932, +0x1E911 => 0x1E933, +0x1E912 => 0x1E934, +0x1E913 => 0x1E935, +0x1E914 => 0x1E936, +0x1E915 => 0x1E937, +0x1E916 => 0x1E938, +0x1E917 => 0x1E939, +0x1E918 => 0x1E93A, +0x1E919 => 0x1E93B, +0x1E91A => 0x1E93C, +0x1E91B => 0x1E93D, +0x1E91C => 0x1E93E, +0x1E91D => 0x1E93F, +0x1E91E => 0x1E940, +0x1E91F => 0x1E941, +0x1E920 => 0x1E942, +0x1E921 => 0x1E943, +]; diff --git a/vendor/opis/string/res/lower.php b/vendor/opis/string/res/lower.php new file mode 100644 index 0000000..b5697d1 --- /dev/null +++ b/vendor/opis/string/res/lower.php @@ -0,0 +1,1396 @@ + 0x61, +0x42 => 0x62, +0x43 => 0x63, +0x44 => 0x64, +0x45 => 0x65, +0x46 => 0x66, +0x47 => 0x67, +0x48 => 0x68, +0x49 => 0x69, +0x4A => 0x6A, +0x4B => 0x6B, +0x4C => 0x6C, +0x4D => 0x6D, +0x4E => 0x6E, +0x4F => 0x6F, +0x50 => 0x70, +0x51 => 0x71, +0x52 => 0x72, +0x53 => 0x73, +0x54 => 0x74, +0x55 => 0x75, +0x56 => 0x76, +0x57 => 0x77, +0x58 => 0x78, +0x59 => 0x79, +0x5A => 0x7A, +0xC0 => 0xE0, +0xC1 => 0xE1, +0xC2 => 0xE2, +0xC3 => 0xE3, +0xC4 => 0xE4, +0xC5 => 0xE5, +0xC6 => 0xE6, +0xC7 => 0xE7, +0xC8 => 0xE8, +0xC9 => 0xE9, +0xCA => 0xEA, +0xCB => 0xEB, +0xCC => 0xEC, +0xCD => 0xED, +0xCE => 0xEE, +0xCF => 0xEF, +0xD0 => 0xF0, +0xD1 => 0xF1, +0xD2 => 0xF2, +0xD3 => 0xF3, +0xD4 => 0xF4, +0xD5 => 0xF5, +0xD6 => 0xF6, +0xD8 => 0xF8, +0xD9 => 0xF9, +0xDA => 0xFA, +0xDB => 0xFB, +0xDC => 0xFC, +0xDD => 0xFD, +0xDE => 0xFE, +0x100 => 0x101, +0x102 => 0x103, +0x104 => 0x105, +0x106 => 0x107, +0x108 => 0x109, +0x10A => 0x10B, +0x10C => 0x10D, +0x10E => 0x10F, +0x110 => 0x111, +0x112 => 0x113, +0x114 => 0x115, +0x116 => 0x117, +0x118 => 0x119, +0x11A => 0x11B, +0x11C => 0x11D, +0x11E => 0x11F, +0x120 => 0x121, +0x122 => 0x123, +0x124 => 0x125, +0x126 => 0x127, +0x128 => 0x129, +0x12A => 0x12B, +0x12C => 0x12D, +0x12E => 0x12F, +0x130 => 0x69, +0x132 => 0x133, +0x134 => 0x135, +0x136 => 0x137, +0x139 => 0x13A, +0x13B => 0x13C, +0x13D => 0x13E, +0x13F => 0x140, +0x141 => 0x142, +0x143 => 0x144, +0x145 => 0x146, +0x147 => 0x148, +0x14A => 0x14B, +0x14C => 0x14D, +0x14E => 0x14F, +0x150 => 0x151, +0x152 => 0x153, +0x154 => 0x155, +0x156 => 0x157, +0x158 => 0x159, +0x15A => 0x15B, +0x15C => 0x15D, +0x15E => 0x15F, +0x160 => 0x161, +0x162 => 0x163, +0x164 => 0x165, +0x166 => 0x167, +0x168 => 0x169, +0x16A => 0x16B, +0x16C => 0x16D, +0x16E => 0x16F, +0x170 => 0x171, +0x172 => 0x173, +0x174 => 0x175, +0x176 => 0x177, +0x178 => 0xFF, +0x179 => 0x17A, +0x17B => 0x17C, +0x17D => 0x17E, +0x181 => 0x253, +0x182 => 0x183, +0x184 => 0x185, +0x186 => 0x254, +0x187 => 0x188, +0x189 => 0x256, +0x18A => 0x257, +0x18B => 0x18C, +0x18E => 0x1DD, +0x18F => 0x259, +0x190 => 0x25B, +0x191 => 0x192, +0x193 => 0x260, +0x194 => 0x263, +0x196 => 0x269, +0x197 => 0x268, +0x198 => 0x199, +0x19C => 0x26F, +0x19D => 0x272, +0x19F => 0x275, +0x1A0 => 0x1A1, +0x1A2 => 0x1A3, +0x1A4 => 0x1A5, +0x1A6 => 0x280, +0x1A7 => 0x1A8, +0x1A9 => 0x283, +0x1AC => 0x1AD, +0x1AE => 0x288, +0x1AF => 0x1B0, +0x1B1 => 0x28A, +0x1B2 => 0x28B, +0x1B3 => 0x1B4, +0x1B5 => 0x1B6, +0x1B7 => 0x292, +0x1B8 => 0x1B9, +0x1BC => 0x1BD, +0x1C4 => 0x1C6, +0x1C5 => 0x1C6, +0x1C7 => 0x1C9, +0x1C8 => 0x1C9, +0x1CA => 0x1CC, +0x1CB => 0x1CC, +0x1CD => 0x1CE, +0x1CF => 0x1D0, +0x1D1 => 0x1D2, +0x1D3 => 0x1D4, +0x1D5 => 0x1D6, +0x1D7 => 0x1D8, +0x1D9 => 0x1DA, +0x1DB => 0x1DC, +0x1DE => 0x1DF, +0x1E0 => 0x1E1, +0x1E2 => 0x1E3, +0x1E4 => 0x1E5, +0x1E6 => 0x1E7, +0x1E8 => 0x1E9, +0x1EA => 0x1EB, +0x1EC => 0x1ED, +0x1EE => 0x1EF, +0x1F1 => 0x1F3, +0x1F2 => 0x1F3, +0x1F4 => 0x1F5, +0x1F6 => 0x195, +0x1F7 => 0x1BF, +0x1F8 => 0x1F9, +0x1FA => 0x1FB, +0x1FC => 0x1FD, +0x1FE => 0x1FF, +0x200 => 0x201, +0x202 => 0x203, +0x204 => 0x205, +0x206 => 0x207, +0x208 => 0x209, +0x20A => 0x20B, +0x20C => 0x20D, +0x20E => 0x20F, +0x210 => 0x211, +0x212 => 0x213, +0x214 => 0x215, +0x216 => 0x217, +0x218 => 0x219, +0x21A => 0x21B, +0x21C => 0x21D, +0x21E => 0x21F, +0x220 => 0x19E, +0x222 => 0x223, +0x224 => 0x225, +0x226 => 0x227, +0x228 => 0x229, +0x22A => 0x22B, +0x22C => 0x22D, +0x22E => 0x22F, +0x230 => 0x231, +0x232 => 0x233, +0x23A => 0x2C65, +0x23B => 0x23C, +0x23D => 0x19A, +0x23E => 0x2C66, +0x241 => 0x242, +0x243 => 0x180, +0x244 => 0x289, +0x245 => 0x28C, +0x246 => 0x247, +0x248 => 0x249, +0x24A => 0x24B, +0x24C => 0x24D, +0x24E => 0x24F, +0x370 => 0x371, +0x372 => 0x373, +0x376 => 0x377, +0x37F => 0x3F3, +0x386 => 0x3AC, +0x388 => 0x3AD, +0x389 => 0x3AE, +0x38A => 0x3AF, +0x38C => 0x3CC, +0x38E => 0x3CD, +0x38F => 0x3CE, +0x391 => 0x3B1, +0x392 => 0x3B2, +0x393 => 0x3B3, +0x394 => 0x3B4, +0x395 => 0x3B5, +0x396 => 0x3B6, +0x397 => 0x3B7, +0x398 => 0x3B8, +0x399 => 0x3B9, +0x39A => 0x3BA, +0x39B => 0x3BB, +0x39C => 0x3BC, +0x39D => 0x3BD, +0x39E => 0x3BE, +0x39F => 0x3BF, +0x3A0 => 0x3C0, +0x3A1 => 0x3C1, +0x3A3 => 0x3C3, +0x3A4 => 0x3C4, +0x3A5 => 0x3C5, +0x3A6 => 0x3C6, +0x3A7 => 0x3C7, +0x3A8 => 0x3C8, +0x3A9 => 0x3C9, +0x3AA => 0x3CA, +0x3AB => 0x3CB, +0x3CF => 0x3D7, +0x3D8 => 0x3D9, +0x3DA => 0x3DB, +0x3DC => 0x3DD, +0x3DE => 0x3DF, +0x3E0 => 0x3E1, +0x3E2 => 0x3E3, +0x3E4 => 0x3E5, +0x3E6 => 0x3E7, +0x3E8 => 0x3E9, +0x3EA => 0x3EB, +0x3EC => 0x3ED, +0x3EE => 0x3EF, +0x3F4 => 0x3B8, +0x3F7 => 0x3F8, +0x3F9 => 0x3F2, +0x3FA => 0x3FB, +0x3FD => 0x37B, +0x3FE => 0x37C, +0x3FF => 0x37D, +0x400 => 0x450, +0x401 => 0x451, +0x402 => 0x452, +0x403 => 0x453, +0x404 => 0x454, +0x405 => 0x455, +0x406 => 0x456, +0x407 => 0x457, +0x408 => 0x458, +0x409 => 0x459, +0x40A => 0x45A, +0x40B => 0x45B, +0x40C => 0x45C, +0x40D => 0x45D, +0x40E => 0x45E, +0x40F => 0x45F, +0x410 => 0x430, +0x411 => 0x431, +0x412 => 0x432, +0x413 => 0x433, +0x414 => 0x434, +0x415 => 0x435, +0x416 => 0x436, +0x417 => 0x437, +0x418 => 0x438, +0x419 => 0x439, +0x41A => 0x43A, +0x41B => 0x43B, +0x41C => 0x43C, +0x41D => 0x43D, +0x41E => 0x43E, +0x41F => 0x43F, +0x420 => 0x440, +0x421 => 0x441, +0x422 => 0x442, +0x423 => 0x443, +0x424 => 0x444, +0x425 => 0x445, +0x426 => 0x446, +0x427 => 0x447, +0x428 => 0x448, +0x429 => 0x449, +0x42A => 0x44A, +0x42B => 0x44B, +0x42C => 0x44C, +0x42D => 0x44D, +0x42E => 0x44E, +0x42F => 0x44F, +0x460 => 0x461, +0x462 => 0x463, +0x464 => 0x465, +0x466 => 0x467, +0x468 => 0x469, +0x46A => 0x46B, +0x46C => 0x46D, +0x46E => 0x46F, +0x470 => 0x471, +0x472 => 0x473, +0x474 => 0x475, +0x476 => 0x477, +0x478 => 0x479, +0x47A => 0x47B, +0x47C => 0x47D, +0x47E => 0x47F, +0x480 => 0x481, +0x48A => 0x48B, +0x48C => 0x48D, +0x48E => 0x48F, +0x490 => 0x491, +0x492 => 0x493, +0x494 => 0x495, +0x496 => 0x497, +0x498 => 0x499, +0x49A => 0x49B, +0x49C => 0x49D, +0x49E => 0x49F, +0x4A0 => 0x4A1, +0x4A2 => 0x4A3, +0x4A4 => 0x4A5, +0x4A6 => 0x4A7, +0x4A8 => 0x4A9, +0x4AA => 0x4AB, +0x4AC => 0x4AD, +0x4AE => 0x4AF, +0x4B0 => 0x4B1, +0x4B2 => 0x4B3, +0x4B4 => 0x4B5, +0x4B6 => 0x4B7, +0x4B8 => 0x4B9, +0x4BA => 0x4BB, +0x4BC => 0x4BD, +0x4BE => 0x4BF, +0x4C0 => 0x4CF, +0x4C1 => 0x4C2, +0x4C3 => 0x4C4, +0x4C5 => 0x4C6, +0x4C7 => 0x4C8, +0x4C9 => 0x4CA, +0x4CB => 0x4CC, +0x4CD => 0x4CE, +0x4D0 => 0x4D1, +0x4D2 => 0x4D3, +0x4D4 => 0x4D5, +0x4D6 => 0x4D7, +0x4D8 => 0x4D9, +0x4DA => 0x4DB, +0x4DC => 0x4DD, +0x4DE => 0x4DF, +0x4E0 => 0x4E1, +0x4E2 => 0x4E3, +0x4E4 => 0x4E5, +0x4E6 => 0x4E7, +0x4E8 => 0x4E9, +0x4EA => 0x4EB, +0x4EC => 0x4ED, +0x4EE => 0x4EF, +0x4F0 => 0x4F1, +0x4F2 => 0x4F3, +0x4F4 => 0x4F5, +0x4F6 => 0x4F7, +0x4F8 => 0x4F9, +0x4FA => 0x4FB, +0x4FC => 0x4FD, +0x4FE => 0x4FF, +0x500 => 0x501, +0x502 => 0x503, +0x504 => 0x505, +0x506 => 0x507, +0x508 => 0x509, +0x50A => 0x50B, +0x50C => 0x50D, +0x50E => 0x50F, +0x510 => 0x511, +0x512 => 0x513, +0x514 => 0x515, +0x516 => 0x517, +0x518 => 0x519, +0x51A => 0x51B, +0x51C => 0x51D, +0x51E => 0x51F, +0x520 => 0x521, +0x522 => 0x523, +0x524 => 0x525, +0x526 => 0x527, +0x528 => 0x529, +0x52A => 0x52B, +0x52C => 0x52D, +0x52E => 0x52F, +0x531 => 0x561, +0x532 => 0x562, +0x533 => 0x563, +0x534 => 0x564, +0x535 => 0x565, +0x536 => 0x566, +0x537 => 0x567, +0x538 => 0x568, +0x539 => 0x569, +0x53A => 0x56A, +0x53B => 0x56B, +0x53C => 0x56C, +0x53D => 0x56D, +0x53E => 0x56E, +0x53F => 0x56F, +0x540 => 0x570, +0x541 => 0x571, +0x542 => 0x572, +0x543 => 0x573, +0x544 => 0x574, +0x545 => 0x575, +0x546 => 0x576, +0x547 => 0x577, +0x548 => 0x578, +0x549 => 0x579, +0x54A => 0x57A, +0x54B => 0x57B, +0x54C => 0x57C, +0x54D => 0x57D, +0x54E => 0x57E, +0x54F => 0x57F, +0x550 => 0x580, +0x551 => 0x581, +0x552 => 0x582, +0x553 => 0x583, +0x554 => 0x584, +0x555 => 0x585, +0x556 => 0x586, +0x10A0 => 0x2D00, +0x10A1 => 0x2D01, +0x10A2 => 0x2D02, +0x10A3 => 0x2D03, +0x10A4 => 0x2D04, +0x10A5 => 0x2D05, +0x10A6 => 0x2D06, +0x10A7 => 0x2D07, +0x10A8 => 0x2D08, +0x10A9 => 0x2D09, +0x10AA => 0x2D0A, +0x10AB => 0x2D0B, +0x10AC => 0x2D0C, +0x10AD => 0x2D0D, +0x10AE => 0x2D0E, +0x10AF => 0x2D0F, +0x10B0 => 0x2D10, +0x10B1 => 0x2D11, +0x10B2 => 0x2D12, +0x10B3 => 0x2D13, +0x10B4 => 0x2D14, +0x10B5 => 0x2D15, +0x10B6 => 0x2D16, +0x10B7 => 0x2D17, +0x10B8 => 0x2D18, +0x10B9 => 0x2D19, +0x10BA => 0x2D1A, +0x10BB => 0x2D1B, +0x10BC => 0x2D1C, +0x10BD => 0x2D1D, +0x10BE => 0x2D1E, +0x10BF => 0x2D1F, +0x10C0 => 0x2D20, +0x10C1 => 0x2D21, +0x10C2 => 0x2D22, +0x10C3 => 0x2D23, +0x10C4 => 0x2D24, +0x10C5 => 0x2D25, +0x10C7 => 0x2D27, +0x10CD => 0x2D2D, +0x13A0 => 0xAB70, +0x13A1 => 0xAB71, +0x13A2 => 0xAB72, +0x13A3 => 0xAB73, +0x13A4 => 0xAB74, +0x13A5 => 0xAB75, +0x13A6 => 0xAB76, +0x13A7 => 0xAB77, +0x13A8 => 0xAB78, +0x13A9 => 0xAB79, +0x13AA => 0xAB7A, +0x13AB => 0xAB7B, +0x13AC => 0xAB7C, +0x13AD => 0xAB7D, +0x13AE => 0xAB7E, +0x13AF => 0xAB7F, +0x13B0 => 0xAB80, +0x13B1 => 0xAB81, +0x13B2 => 0xAB82, +0x13B3 => 0xAB83, +0x13B4 => 0xAB84, +0x13B5 => 0xAB85, +0x13B6 => 0xAB86, +0x13B7 => 0xAB87, +0x13B8 => 0xAB88, +0x13B9 => 0xAB89, +0x13BA => 0xAB8A, +0x13BB => 0xAB8B, +0x13BC => 0xAB8C, +0x13BD => 0xAB8D, +0x13BE => 0xAB8E, +0x13BF => 0xAB8F, +0x13C0 => 0xAB90, +0x13C1 => 0xAB91, +0x13C2 => 0xAB92, +0x13C3 => 0xAB93, +0x13C4 => 0xAB94, +0x13C5 => 0xAB95, +0x13C6 => 0xAB96, +0x13C7 => 0xAB97, +0x13C8 => 0xAB98, +0x13C9 => 0xAB99, +0x13CA => 0xAB9A, +0x13CB => 0xAB9B, +0x13CC => 0xAB9C, +0x13CD => 0xAB9D, +0x13CE => 0xAB9E, +0x13CF => 0xAB9F, +0x13D0 => 0xABA0, +0x13D1 => 0xABA1, +0x13D2 => 0xABA2, +0x13D3 => 0xABA3, +0x13D4 => 0xABA4, +0x13D5 => 0xABA5, +0x13D6 => 0xABA6, +0x13D7 => 0xABA7, +0x13D8 => 0xABA8, +0x13D9 => 0xABA9, +0x13DA => 0xABAA, +0x13DB => 0xABAB, +0x13DC => 0xABAC, +0x13DD => 0xABAD, +0x13DE => 0xABAE, +0x13DF => 0xABAF, +0x13E0 => 0xABB0, +0x13E1 => 0xABB1, +0x13E2 => 0xABB2, +0x13E3 => 0xABB3, +0x13E4 => 0xABB4, +0x13E5 => 0xABB5, +0x13E6 => 0xABB6, +0x13E7 => 0xABB7, +0x13E8 => 0xABB8, +0x13E9 => 0xABB9, +0x13EA => 0xABBA, +0x13EB => 0xABBB, +0x13EC => 0xABBC, +0x13ED => 0xABBD, +0x13EE => 0xABBE, +0x13EF => 0xABBF, +0x13F0 => 0x13F8, +0x13F1 => 0x13F9, +0x13F2 => 0x13FA, +0x13F3 => 0x13FB, +0x13F4 => 0x13FC, +0x13F5 => 0x13FD, +0x1C90 => 0x10D0, +0x1C91 => 0x10D1, +0x1C92 => 0x10D2, +0x1C93 => 0x10D3, +0x1C94 => 0x10D4, +0x1C95 => 0x10D5, +0x1C96 => 0x10D6, +0x1C97 => 0x10D7, +0x1C98 => 0x10D8, +0x1C99 => 0x10D9, +0x1C9A => 0x10DA, +0x1C9B => 0x10DB, +0x1C9C => 0x10DC, +0x1C9D => 0x10DD, +0x1C9E => 0x10DE, +0x1C9F => 0x10DF, +0x1CA0 => 0x10E0, +0x1CA1 => 0x10E1, +0x1CA2 => 0x10E2, +0x1CA3 => 0x10E3, +0x1CA4 => 0x10E4, +0x1CA5 => 0x10E5, +0x1CA6 => 0x10E6, +0x1CA7 => 0x10E7, +0x1CA8 => 0x10E8, +0x1CA9 => 0x10E9, +0x1CAA => 0x10EA, +0x1CAB => 0x10EB, +0x1CAC => 0x10EC, +0x1CAD => 0x10ED, +0x1CAE => 0x10EE, +0x1CAF => 0x10EF, +0x1CB0 => 0x10F0, +0x1CB1 => 0x10F1, +0x1CB2 => 0x10F2, +0x1CB3 => 0x10F3, +0x1CB4 => 0x10F4, +0x1CB5 => 0x10F5, +0x1CB6 => 0x10F6, +0x1CB7 => 0x10F7, +0x1CB8 => 0x10F8, +0x1CB9 => 0x10F9, +0x1CBA => 0x10FA, +0x1CBD => 0x10FD, +0x1CBE => 0x10FE, +0x1CBF => 0x10FF, +0x1E00 => 0x1E01, +0x1E02 => 0x1E03, +0x1E04 => 0x1E05, +0x1E06 => 0x1E07, +0x1E08 => 0x1E09, +0x1E0A => 0x1E0B, +0x1E0C => 0x1E0D, +0x1E0E => 0x1E0F, +0x1E10 => 0x1E11, +0x1E12 => 0x1E13, +0x1E14 => 0x1E15, +0x1E16 => 0x1E17, +0x1E18 => 0x1E19, +0x1E1A => 0x1E1B, +0x1E1C => 0x1E1D, +0x1E1E => 0x1E1F, +0x1E20 => 0x1E21, +0x1E22 => 0x1E23, +0x1E24 => 0x1E25, +0x1E26 => 0x1E27, +0x1E28 => 0x1E29, +0x1E2A => 0x1E2B, +0x1E2C => 0x1E2D, +0x1E2E => 0x1E2F, +0x1E30 => 0x1E31, +0x1E32 => 0x1E33, +0x1E34 => 0x1E35, +0x1E36 => 0x1E37, +0x1E38 => 0x1E39, +0x1E3A => 0x1E3B, +0x1E3C => 0x1E3D, +0x1E3E => 0x1E3F, +0x1E40 => 0x1E41, +0x1E42 => 0x1E43, +0x1E44 => 0x1E45, +0x1E46 => 0x1E47, +0x1E48 => 0x1E49, +0x1E4A => 0x1E4B, +0x1E4C => 0x1E4D, +0x1E4E => 0x1E4F, +0x1E50 => 0x1E51, +0x1E52 => 0x1E53, +0x1E54 => 0x1E55, +0x1E56 => 0x1E57, +0x1E58 => 0x1E59, +0x1E5A => 0x1E5B, +0x1E5C => 0x1E5D, +0x1E5E => 0x1E5F, +0x1E60 => 0x1E61, +0x1E62 => 0x1E63, +0x1E64 => 0x1E65, +0x1E66 => 0x1E67, +0x1E68 => 0x1E69, +0x1E6A => 0x1E6B, +0x1E6C => 0x1E6D, +0x1E6E => 0x1E6F, +0x1E70 => 0x1E71, +0x1E72 => 0x1E73, +0x1E74 => 0x1E75, +0x1E76 => 0x1E77, +0x1E78 => 0x1E79, +0x1E7A => 0x1E7B, +0x1E7C => 0x1E7D, +0x1E7E => 0x1E7F, +0x1E80 => 0x1E81, +0x1E82 => 0x1E83, +0x1E84 => 0x1E85, +0x1E86 => 0x1E87, +0x1E88 => 0x1E89, +0x1E8A => 0x1E8B, +0x1E8C => 0x1E8D, +0x1E8E => 0x1E8F, +0x1E90 => 0x1E91, +0x1E92 => 0x1E93, +0x1E94 => 0x1E95, +0x1E9E => 0xDF, +0x1EA0 => 0x1EA1, +0x1EA2 => 0x1EA3, +0x1EA4 => 0x1EA5, +0x1EA6 => 0x1EA7, +0x1EA8 => 0x1EA9, +0x1EAA => 0x1EAB, +0x1EAC => 0x1EAD, +0x1EAE => 0x1EAF, +0x1EB0 => 0x1EB1, +0x1EB2 => 0x1EB3, +0x1EB4 => 0x1EB5, +0x1EB6 => 0x1EB7, +0x1EB8 => 0x1EB9, +0x1EBA => 0x1EBB, +0x1EBC => 0x1EBD, +0x1EBE => 0x1EBF, +0x1EC0 => 0x1EC1, +0x1EC2 => 0x1EC3, +0x1EC4 => 0x1EC5, +0x1EC6 => 0x1EC7, +0x1EC8 => 0x1EC9, +0x1ECA => 0x1ECB, +0x1ECC => 0x1ECD, +0x1ECE => 0x1ECF, +0x1ED0 => 0x1ED1, +0x1ED2 => 0x1ED3, +0x1ED4 => 0x1ED5, +0x1ED6 => 0x1ED7, +0x1ED8 => 0x1ED9, +0x1EDA => 0x1EDB, +0x1EDC => 0x1EDD, +0x1EDE => 0x1EDF, +0x1EE0 => 0x1EE1, +0x1EE2 => 0x1EE3, +0x1EE4 => 0x1EE5, +0x1EE6 => 0x1EE7, +0x1EE8 => 0x1EE9, +0x1EEA => 0x1EEB, +0x1EEC => 0x1EED, +0x1EEE => 0x1EEF, +0x1EF0 => 0x1EF1, +0x1EF2 => 0x1EF3, +0x1EF4 => 0x1EF5, +0x1EF6 => 0x1EF7, +0x1EF8 => 0x1EF9, +0x1EFA => 0x1EFB, +0x1EFC => 0x1EFD, +0x1EFE => 0x1EFF, +0x1F08 => 0x1F00, +0x1F09 => 0x1F01, +0x1F0A => 0x1F02, +0x1F0B => 0x1F03, +0x1F0C => 0x1F04, +0x1F0D => 0x1F05, +0x1F0E => 0x1F06, +0x1F0F => 0x1F07, +0x1F18 => 0x1F10, +0x1F19 => 0x1F11, +0x1F1A => 0x1F12, +0x1F1B => 0x1F13, +0x1F1C => 0x1F14, +0x1F1D => 0x1F15, +0x1F28 => 0x1F20, +0x1F29 => 0x1F21, +0x1F2A => 0x1F22, +0x1F2B => 0x1F23, +0x1F2C => 0x1F24, +0x1F2D => 0x1F25, +0x1F2E => 0x1F26, +0x1F2F => 0x1F27, +0x1F38 => 0x1F30, +0x1F39 => 0x1F31, +0x1F3A => 0x1F32, +0x1F3B => 0x1F33, +0x1F3C => 0x1F34, +0x1F3D => 0x1F35, +0x1F3E => 0x1F36, +0x1F3F => 0x1F37, +0x1F48 => 0x1F40, +0x1F49 => 0x1F41, +0x1F4A => 0x1F42, +0x1F4B => 0x1F43, +0x1F4C => 0x1F44, +0x1F4D => 0x1F45, +0x1F59 => 0x1F51, +0x1F5B => 0x1F53, +0x1F5D => 0x1F55, +0x1F5F => 0x1F57, +0x1F68 => 0x1F60, +0x1F69 => 0x1F61, +0x1F6A => 0x1F62, +0x1F6B => 0x1F63, +0x1F6C => 0x1F64, +0x1F6D => 0x1F65, +0x1F6E => 0x1F66, +0x1F6F => 0x1F67, +0x1F88 => 0x1F80, +0x1F89 => 0x1F81, +0x1F8A => 0x1F82, +0x1F8B => 0x1F83, +0x1F8C => 0x1F84, +0x1F8D => 0x1F85, +0x1F8E => 0x1F86, +0x1F8F => 0x1F87, +0x1F98 => 0x1F90, +0x1F99 => 0x1F91, +0x1F9A => 0x1F92, +0x1F9B => 0x1F93, +0x1F9C => 0x1F94, +0x1F9D => 0x1F95, +0x1F9E => 0x1F96, +0x1F9F => 0x1F97, +0x1FA8 => 0x1FA0, +0x1FA9 => 0x1FA1, +0x1FAA => 0x1FA2, +0x1FAB => 0x1FA3, +0x1FAC => 0x1FA4, +0x1FAD => 0x1FA5, +0x1FAE => 0x1FA6, +0x1FAF => 0x1FA7, +0x1FB8 => 0x1FB0, +0x1FB9 => 0x1FB1, +0x1FBA => 0x1F70, +0x1FBB => 0x1F71, +0x1FBC => 0x1FB3, +0x1FC8 => 0x1F72, +0x1FC9 => 0x1F73, +0x1FCA => 0x1F74, +0x1FCB => 0x1F75, +0x1FCC => 0x1FC3, +0x1FD8 => 0x1FD0, +0x1FD9 => 0x1FD1, +0x1FDA => 0x1F76, +0x1FDB => 0x1F77, +0x1FE8 => 0x1FE0, +0x1FE9 => 0x1FE1, +0x1FEA => 0x1F7A, +0x1FEB => 0x1F7B, +0x1FEC => 0x1FE5, +0x1FF8 => 0x1F78, +0x1FF9 => 0x1F79, +0x1FFA => 0x1F7C, +0x1FFB => 0x1F7D, +0x1FFC => 0x1FF3, +0x2126 => 0x3C9, +0x212A => 0x6B, +0x212B => 0xE5, +0x2132 => 0x214E, +0x2160 => 0x2170, +0x2161 => 0x2171, +0x2162 => 0x2172, +0x2163 => 0x2173, +0x2164 => 0x2174, +0x2165 => 0x2175, +0x2166 => 0x2176, +0x2167 => 0x2177, +0x2168 => 0x2178, +0x2169 => 0x2179, +0x216A => 0x217A, +0x216B => 0x217B, +0x216C => 0x217C, +0x216D => 0x217D, +0x216E => 0x217E, +0x216F => 0x217F, +0x2183 => 0x2184, +0x24B6 => 0x24D0, +0x24B7 => 0x24D1, +0x24B8 => 0x24D2, +0x24B9 => 0x24D3, +0x24BA => 0x24D4, +0x24BB => 0x24D5, +0x24BC => 0x24D6, +0x24BD => 0x24D7, +0x24BE => 0x24D8, +0x24BF => 0x24D9, +0x24C0 => 0x24DA, +0x24C1 => 0x24DB, +0x24C2 => 0x24DC, +0x24C3 => 0x24DD, +0x24C4 => 0x24DE, +0x24C5 => 0x24DF, +0x24C6 => 0x24E0, +0x24C7 => 0x24E1, +0x24C8 => 0x24E2, +0x24C9 => 0x24E3, +0x24CA => 0x24E4, +0x24CB => 0x24E5, +0x24CC => 0x24E6, +0x24CD => 0x24E7, +0x24CE => 0x24E8, +0x24CF => 0x24E9, +0x2C00 => 0x2C30, +0x2C01 => 0x2C31, +0x2C02 => 0x2C32, +0x2C03 => 0x2C33, +0x2C04 => 0x2C34, +0x2C05 => 0x2C35, +0x2C06 => 0x2C36, +0x2C07 => 0x2C37, +0x2C08 => 0x2C38, +0x2C09 => 0x2C39, +0x2C0A => 0x2C3A, +0x2C0B => 0x2C3B, +0x2C0C => 0x2C3C, +0x2C0D => 0x2C3D, +0x2C0E => 0x2C3E, +0x2C0F => 0x2C3F, +0x2C10 => 0x2C40, +0x2C11 => 0x2C41, +0x2C12 => 0x2C42, +0x2C13 => 0x2C43, +0x2C14 => 0x2C44, +0x2C15 => 0x2C45, +0x2C16 => 0x2C46, +0x2C17 => 0x2C47, +0x2C18 => 0x2C48, +0x2C19 => 0x2C49, +0x2C1A => 0x2C4A, +0x2C1B => 0x2C4B, +0x2C1C => 0x2C4C, +0x2C1D => 0x2C4D, +0x2C1E => 0x2C4E, +0x2C1F => 0x2C4F, +0x2C20 => 0x2C50, +0x2C21 => 0x2C51, +0x2C22 => 0x2C52, +0x2C23 => 0x2C53, +0x2C24 => 0x2C54, +0x2C25 => 0x2C55, +0x2C26 => 0x2C56, +0x2C27 => 0x2C57, +0x2C28 => 0x2C58, +0x2C29 => 0x2C59, +0x2C2A => 0x2C5A, +0x2C2B => 0x2C5B, +0x2C2C => 0x2C5C, +0x2C2D => 0x2C5D, +0x2C2E => 0x2C5E, +0x2C60 => 0x2C61, +0x2C62 => 0x26B, +0x2C63 => 0x1D7D, +0x2C64 => 0x27D, +0x2C67 => 0x2C68, +0x2C69 => 0x2C6A, +0x2C6B => 0x2C6C, +0x2C6D => 0x251, +0x2C6E => 0x271, +0x2C6F => 0x250, +0x2C70 => 0x252, +0x2C72 => 0x2C73, +0x2C75 => 0x2C76, +0x2C7E => 0x23F, +0x2C7F => 0x240, +0x2C80 => 0x2C81, +0x2C82 => 0x2C83, +0x2C84 => 0x2C85, +0x2C86 => 0x2C87, +0x2C88 => 0x2C89, +0x2C8A => 0x2C8B, +0x2C8C => 0x2C8D, +0x2C8E => 0x2C8F, +0x2C90 => 0x2C91, +0x2C92 => 0x2C93, +0x2C94 => 0x2C95, +0x2C96 => 0x2C97, +0x2C98 => 0x2C99, +0x2C9A => 0x2C9B, +0x2C9C => 0x2C9D, +0x2C9E => 0x2C9F, +0x2CA0 => 0x2CA1, +0x2CA2 => 0x2CA3, +0x2CA4 => 0x2CA5, +0x2CA6 => 0x2CA7, +0x2CA8 => 0x2CA9, +0x2CAA => 0x2CAB, +0x2CAC => 0x2CAD, +0x2CAE => 0x2CAF, +0x2CB0 => 0x2CB1, +0x2CB2 => 0x2CB3, +0x2CB4 => 0x2CB5, +0x2CB6 => 0x2CB7, +0x2CB8 => 0x2CB9, +0x2CBA => 0x2CBB, +0x2CBC => 0x2CBD, +0x2CBE => 0x2CBF, +0x2CC0 => 0x2CC1, +0x2CC2 => 0x2CC3, +0x2CC4 => 0x2CC5, +0x2CC6 => 0x2CC7, +0x2CC8 => 0x2CC9, +0x2CCA => 0x2CCB, +0x2CCC => 0x2CCD, +0x2CCE => 0x2CCF, +0x2CD0 => 0x2CD1, +0x2CD2 => 0x2CD3, +0x2CD4 => 0x2CD5, +0x2CD6 => 0x2CD7, +0x2CD8 => 0x2CD9, +0x2CDA => 0x2CDB, +0x2CDC => 0x2CDD, +0x2CDE => 0x2CDF, +0x2CE0 => 0x2CE1, +0x2CE2 => 0x2CE3, +0x2CEB => 0x2CEC, +0x2CED => 0x2CEE, +0x2CF2 => 0x2CF3, +0xA640 => 0xA641, +0xA642 => 0xA643, +0xA644 => 0xA645, +0xA646 => 0xA647, +0xA648 => 0xA649, +0xA64A => 0xA64B, +0xA64C => 0xA64D, +0xA64E => 0xA64F, +0xA650 => 0xA651, +0xA652 => 0xA653, +0xA654 => 0xA655, +0xA656 => 0xA657, +0xA658 => 0xA659, +0xA65A => 0xA65B, +0xA65C => 0xA65D, +0xA65E => 0xA65F, +0xA660 => 0xA661, +0xA662 => 0xA663, +0xA664 => 0xA665, +0xA666 => 0xA667, +0xA668 => 0xA669, +0xA66A => 0xA66B, +0xA66C => 0xA66D, +0xA680 => 0xA681, +0xA682 => 0xA683, +0xA684 => 0xA685, +0xA686 => 0xA687, +0xA688 => 0xA689, +0xA68A => 0xA68B, +0xA68C => 0xA68D, +0xA68E => 0xA68F, +0xA690 => 0xA691, +0xA692 => 0xA693, +0xA694 => 0xA695, +0xA696 => 0xA697, +0xA698 => 0xA699, +0xA69A => 0xA69B, +0xA722 => 0xA723, +0xA724 => 0xA725, +0xA726 => 0xA727, +0xA728 => 0xA729, +0xA72A => 0xA72B, +0xA72C => 0xA72D, +0xA72E => 0xA72F, +0xA732 => 0xA733, +0xA734 => 0xA735, +0xA736 => 0xA737, +0xA738 => 0xA739, +0xA73A => 0xA73B, +0xA73C => 0xA73D, +0xA73E => 0xA73F, +0xA740 => 0xA741, +0xA742 => 0xA743, +0xA744 => 0xA745, +0xA746 => 0xA747, +0xA748 => 0xA749, +0xA74A => 0xA74B, +0xA74C => 0xA74D, +0xA74E => 0xA74F, +0xA750 => 0xA751, +0xA752 => 0xA753, +0xA754 => 0xA755, +0xA756 => 0xA757, +0xA758 => 0xA759, +0xA75A => 0xA75B, +0xA75C => 0xA75D, +0xA75E => 0xA75F, +0xA760 => 0xA761, +0xA762 => 0xA763, +0xA764 => 0xA765, +0xA766 => 0xA767, +0xA768 => 0xA769, +0xA76A => 0xA76B, +0xA76C => 0xA76D, +0xA76E => 0xA76F, +0xA779 => 0xA77A, +0xA77B => 0xA77C, +0xA77D => 0x1D79, +0xA77E => 0xA77F, +0xA780 => 0xA781, +0xA782 => 0xA783, +0xA784 => 0xA785, +0xA786 => 0xA787, +0xA78B => 0xA78C, +0xA78D => 0x265, +0xA790 => 0xA791, +0xA792 => 0xA793, +0xA796 => 0xA797, +0xA798 => 0xA799, +0xA79A => 0xA79B, +0xA79C => 0xA79D, +0xA79E => 0xA79F, +0xA7A0 => 0xA7A1, +0xA7A2 => 0xA7A3, +0xA7A4 => 0xA7A5, +0xA7A6 => 0xA7A7, +0xA7A8 => 0xA7A9, +0xA7AA => 0x266, +0xA7AB => 0x25C, +0xA7AC => 0x261, +0xA7AD => 0x26C, +0xA7AE => 0x26A, +0xA7B0 => 0x29E, +0xA7B1 => 0x287, +0xA7B2 => 0x29D, +0xA7B3 => 0xAB53, +0xA7B4 => 0xA7B5, +0xA7B6 => 0xA7B7, +0xA7B8 => 0xA7B9, +0xA7BA => 0xA7BB, +0xA7BC => 0xA7BD, +0xA7BE => 0xA7BF, +0xA7C2 => 0xA7C3, +0xA7C4 => 0xA794, +0xA7C5 => 0x282, +0xA7C6 => 0x1D8E, +0xA7C7 => 0xA7C8, +0xA7C9 => 0xA7CA, +0xA7F5 => 0xA7F6, +0xFF21 => 0xFF41, +0xFF22 => 0xFF42, +0xFF23 => 0xFF43, +0xFF24 => 0xFF44, +0xFF25 => 0xFF45, +0xFF26 => 0xFF46, +0xFF27 => 0xFF47, +0xFF28 => 0xFF48, +0xFF29 => 0xFF49, +0xFF2A => 0xFF4A, +0xFF2B => 0xFF4B, +0xFF2C => 0xFF4C, +0xFF2D => 0xFF4D, +0xFF2E => 0xFF4E, +0xFF2F => 0xFF4F, +0xFF30 => 0xFF50, +0xFF31 => 0xFF51, +0xFF32 => 0xFF52, +0xFF33 => 0xFF53, +0xFF34 => 0xFF54, +0xFF35 => 0xFF55, +0xFF36 => 0xFF56, +0xFF37 => 0xFF57, +0xFF38 => 0xFF58, +0xFF39 => 0xFF59, +0xFF3A => 0xFF5A, +0x10400 => 0x10428, +0x10401 => 0x10429, +0x10402 => 0x1042A, +0x10403 => 0x1042B, +0x10404 => 0x1042C, +0x10405 => 0x1042D, +0x10406 => 0x1042E, +0x10407 => 0x1042F, +0x10408 => 0x10430, +0x10409 => 0x10431, +0x1040A => 0x10432, +0x1040B => 0x10433, +0x1040C => 0x10434, +0x1040D => 0x10435, +0x1040E => 0x10436, +0x1040F => 0x10437, +0x10410 => 0x10438, +0x10411 => 0x10439, +0x10412 => 0x1043A, +0x10413 => 0x1043B, +0x10414 => 0x1043C, +0x10415 => 0x1043D, +0x10416 => 0x1043E, +0x10417 => 0x1043F, +0x10418 => 0x10440, +0x10419 => 0x10441, +0x1041A => 0x10442, +0x1041B => 0x10443, +0x1041C => 0x10444, +0x1041D => 0x10445, +0x1041E => 0x10446, +0x1041F => 0x10447, +0x10420 => 0x10448, +0x10421 => 0x10449, +0x10422 => 0x1044A, +0x10423 => 0x1044B, +0x10424 => 0x1044C, +0x10425 => 0x1044D, +0x10426 => 0x1044E, +0x10427 => 0x1044F, +0x104B0 => 0x104D8, +0x104B1 => 0x104D9, +0x104B2 => 0x104DA, +0x104B3 => 0x104DB, +0x104B4 => 0x104DC, +0x104B5 => 0x104DD, +0x104B6 => 0x104DE, +0x104B7 => 0x104DF, +0x104B8 => 0x104E0, +0x104B9 => 0x104E1, +0x104BA => 0x104E2, +0x104BB => 0x104E3, +0x104BC => 0x104E4, +0x104BD => 0x104E5, +0x104BE => 0x104E6, +0x104BF => 0x104E7, +0x104C0 => 0x104E8, +0x104C1 => 0x104E9, +0x104C2 => 0x104EA, +0x104C3 => 0x104EB, +0x104C4 => 0x104EC, +0x104C5 => 0x104ED, +0x104C6 => 0x104EE, +0x104C7 => 0x104EF, +0x104C8 => 0x104F0, +0x104C9 => 0x104F1, +0x104CA => 0x104F2, +0x104CB => 0x104F3, +0x104CC => 0x104F4, +0x104CD => 0x104F5, +0x104CE => 0x104F6, +0x104CF => 0x104F7, +0x104D0 => 0x104F8, +0x104D1 => 0x104F9, +0x104D2 => 0x104FA, +0x104D3 => 0x104FB, +0x10C80 => 0x10CC0, +0x10C81 => 0x10CC1, +0x10C82 => 0x10CC2, +0x10C83 => 0x10CC3, +0x10C84 => 0x10CC4, +0x10C85 => 0x10CC5, +0x10C86 => 0x10CC6, +0x10C87 => 0x10CC7, +0x10C88 => 0x10CC8, +0x10C89 => 0x10CC9, +0x10C8A => 0x10CCA, +0x10C8B => 0x10CCB, +0x10C8C => 0x10CCC, +0x10C8D => 0x10CCD, +0x10C8E => 0x10CCE, +0x10C8F => 0x10CCF, +0x10C90 => 0x10CD0, +0x10C91 => 0x10CD1, +0x10C92 => 0x10CD2, +0x10C93 => 0x10CD3, +0x10C94 => 0x10CD4, +0x10C95 => 0x10CD5, +0x10C96 => 0x10CD6, +0x10C97 => 0x10CD7, +0x10C98 => 0x10CD8, +0x10C99 => 0x10CD9, +0x10C9A => 0x10CDA, +0x10C9B => 0x10CDB, +0x10C9C => 0x10CDC, +0x10C9D => 0x10CDD, +0x10C9E => 0x10CDE, +0x10C9F => 0x10CDF, +0x10CA0 => 0x10CE0, +0x10CA1 => 0x10CE1, +0x10CA2 => 0x10CE2, +0x10CA3 => 0x10CE3, +0x10CA4 => 0x10CE4, +0x10CA5 => 0x10CE5, +0x10CA6 => 0x10CE6, +0x10CA7 => 0x10CE7, +0x10CA8 => 0x10CE8, +0x10CA9 => 0x10CE9, +0x10CAA => 0x10CEA, +0x10CAB => 0x10CEB, +0x10CAC => 0x10CEC, +0x10CAD => 0x10CED, +0x10CAE => 0x10CEE, +0x10CAF => 0x10CEF, +0x10CB0 => 0x10CF0, +0x10CB1 => 0x10CF1, +0x10CB2 => 0x10CF2, +0x118A0 => 0x118C0, +0x118A1 => 0x118C1, +0x118A2 => 0x118C2, +0x118A3 => 0x118C3, +0x118A4 => 0x118C4, +0x118A5 => 0x118C5, +0x118A6 => 0x118C6, +0x118A7 => 0x118C7, +0x118A8 => 0x118C8, +0x118A9 => 0x118C9, +0x118AA => 0x118CA, +0x118AB => 0x118CB, +0x118AC => 0x118CC, +0x118AD => 0x118CD, +0x118AE => 0x118CE, +0x118AF => 0x118CF, +0x118B0 => 0x118D0, +0x118B1 => 0x118D1, +0x118B2 => 0x118D2, +0x118B3 => 0x118D3, +0x118B4 => 0x118D4, +0x118B5 => 0x118D5, +0x118B6 => 0x118D6, +0x118B7 => 0x118D7, +0x118B8 => 0x118D8, +0x118B9 => 0x118D9, +0x118BA => 0x118DA, +0x118BB => 0x118DB, +0x118BC => 0x118DC, +0x118BD => 0x118DD, +0x118BE => 0x118DE, +0x118BF => 0x118DF, +0x16E40 => 0x16E60, +0x16E41 => 0x16E61, +0x16E42 => 0x16E62, +0x16E43 => 0x16E63, +0x16E44 => 0x16E64, +0x16E45 => 0x16E65, +0x16E46 => 0x16E66, +0x16E47 => 0x16E67, +0x16E48 => 0x16E68, +0x16E49 => 0x16E69, +0x16E4A => 0x16E6A, +0x16E4B => 0x16E6B, +0x16E4C => 0x16E6C, +0x16E4D => 0x16E6D, +0x16E4E => 0x16E6E, +0x16E4F => 0x16E6F, +0x16E50 => 0x16E70, +0x16E51 => 0x16E71, +0x16E52 => 0x16E72, +0x16E53 => 0x16E73, +0x16E54 => 0x16E74, +0x16E55 => 0x16E75, +0x16E56 => 0x16E76, +0x16E57 => 0x16E77, +0x16E58 => 0x16E78, +0x16E59 => 0x16E79, +0x16E5A => 0x16E7A, +0x16E5B => 0x16E7B, +0x16E5C => 0x16E7C, +0x16E5D => 0x16E7D, +0x16E5E => 0x16E7E, +0x16E5F => 0x16E7F, +0x1E900 => 0x1E922, +0x1E901 => 0x1E923, +0x1E902 => 0x1E924, +0x1E903 => 0x1E925, +0x1E904 => 0x1E926, +0x1E905 => 0x1E927, +0x1E906 => 0x1E928, +0x1E907 => 0x1E929, +0x1E908 => 0x1E92A, +0x1E909 => 0x1E92B, +0x1E90A => 0x1E92C, +0x1E90B => 0x1E92D, +0x1E90C => 0x1E92E, +0x1E90D => 0x1E92F, +0x1E90E => 0x1E930, +0x1E90F => 0x1E931, +0x1E910 => 0x1E932, +0x1E911 => 0x1E933, +0x1E912 => 0x1E934, +0x1E913 => 0x1E935, +0x1E914 => 0x1E936, +0x1E915 => 0x1E937, +0x1E916 => 0x1E938, +0x1E917 => 0x1E939, +0x1E918 => 0x1E93A, +0x1E919 => 0x1E93B, +0x1E91A => 0x1E93C, +0x1E91B => 0x1E93D, +0x1E91C => 0x1E93E, +0x1E91D => 0x1E93F, +0x1E91E => 0x1E940, +0x1E91F => 0x1E941, +0x1E920 => 0x1E942, +0x1E921 => 0x1E943, +]; diff --git a/vendor/opis/string/res/upper.php b/vendor/opis/string/res/upper.php new file mode 100644 index 0000000..376ce6e --- /dev/null +++ b/vendor/opis/string/res/upper.php @@ -0,0 +1,1413 @@ + 0x41, +0x62 => 0x42, +0x63 => 0x43, +0x64 => 0x44, +0x65 => 0x45, +0x66 => 0x46, +0x67 => 0x47, +0x68 => 0x48, +0x69 => 0x49, +0x6A => 0x4A, +0x6B => 0x4B, +0x6C => 0x4C, +0x6D => 0x4D, +0x6E => 0x4E, +0x6F => 0x4F, +0x70 => 0x50, +0x71 => 0x51, +0x72 => 0x52, +0x73 => 0x53, +0x74 => 0x54, +0x75 => 0x55, +0x76 => 0x56, +0x77 => 0x57, +0x78 => 0x58, +0x79 => 0x59, +0x7A => 0x5A, +0xB5 => 0x39C, +0xE0 => 0xC0, +0xE1 => 0xC1, +0xE2 => 0xC2, +0xE3 => 0xC3, +0xE4 => 0xC4, +0xE5 => 0xC5, +0xE6 => 0xC6, +0xE7 => 0xC7, +0xE8 => 0xC8, +0xE9 => 0xC9, +0xEA => 0xCA, +0xEB => 0xCB, +0xEC => 0xCC, +0xED => 0xCD, +0xEE => 0xCE, +0xEF => 0xCF, +0xF0 => 0xD0, +0xF1 => 0xD1, +0xF2 => 0xD2, +0xF3 => 0xD3, +0xF4 => 0xD4, +0xF5 => 0xD5, +0xF6 => 0xD6, +0xF8 => 0xD8, +0xF9 => 0xD9, +0xFA => 0xDA, +0xFB => 0xDB, +0xFC => 0xDC, +0xFD => 0xDD, +0xFE => 0xDE, +0xFF => 0x178, +0x101 => 0x100, +0x103 => 0x102, +0x105 => 0x104, +0x107 => 0x106, +0x109 => 0x108, +0x10B => 0x10A, +0x10D => 0x10C, +0x10F => 0x10E, +0x111 => 0x110, +0x113 => 0x112, +0x115 => 0x114, +0x117 => 0x116, +0x119 => 0x118, +0x11B => 0x11A, +0x11D => 0x11C, +0x11F => 0x11E, +0x121 => 0x120, +0x123 => 0x122, +0x125 => 0x124, +0x127 => 0x126, +0x129 => 0x128, +0x12B => 0x12A, +0x12D => 0x12C, +0x12F => 0x12E, +0x131 => 0x49, +0x133 => 0x132, +0x135 => 0x134, +0x137 => 0x136, +0x13A => 0x139, +0x13C => 0x13B, +0x13E => 0x13D, +0x140 => 0x13F, +0x142 => 0x141, +0x144 => 0x143, +0x146 => 0x145, +0x148 => 0x147, +0x14B => 0x14A, +0x14D => 0x14C, +0x14F => 0x14E, +0x151 => 0x150, +0x153 => 0x152, +0x155 => 0x154, +0x157 => 0x156, +0x159 => 0x158, +0x15B => 0x15A, +0x15D => 0x15C, +0x15F => 0x15E, +0x161 => 0x160, +0x163 => 0x162, +0x165 => 0x164, +0x167 => 0x166, +0x169 => 0x168, +0x16B => 0x16A, +0x16D => 0x16C, +0x16F => 0x16E, +0x171 => 0x170, +0x173 => 0x172, +0x175 => 0x174, +0x177 => 0x176, +0x17A => 0x179, +0x17C => 0x17B, +0x17E => 0x17D, +0x17F => 0x53, +0x180 => 0x243, +0x183 => 0x182, +0x185 => 0x184, +0x188 => 0x187, +0x18C => 0x18B, +0x192 => 0x191, +0x195 => 0x1F6, +0x199 => 0x198, +0x19A => 0x23D, +0x19E => 0x220, +0x1A1 => 0x1A0, +0x1A3 => 0x1A2, +0x1A5 => 0x1A4, +0x1A8 => 0x1A7, +0x1AD => 0x1AC, +0x1B0 => 0x1AF, +0x1B4 => 0x1B3, +0x1B6 => 0x1B5, +0x1B9 => 0x1B8, +0x1BD => 0x1BC, +0x1BF => 0x1F7, +0x1C5 => 0x1C4, +0x1C6 => 0x1C4, +0x1C8 => 0x1C7, +0x1C9 => 0x1C7, +0x1CB => 0x1CA, +0x1CC => 0x1CA, +0x1CE => 0x1CD, +0x1D0 => 0x1CF, +0x1D2 => 0x1D1, +0x1D4 => 0x1D3, +0x1D6 => 0x1D5, +0x1D8 => 0x1D7, +0x1DA => 0x1D9, +0x1DC => 0x1DB, +0x1DD => 0x18E, +0x1DF => 0x1DE, +0x1E1 => 0x1E0, +0x1E3 => 0x1E2, +0x1E5 => 0x1E4, +0x1E7 => 0x1E6, +0x1E9 => 0x1E8, +0x1EB => 0x1EA, +0x1ED => 0x1EC, +0x1EF => 0x1EE, +0x1F2 => 0x1F1, +0x1F3 => 0x1F1, +0x1F5 => 0x1F4, +0x1F9 => 0x1F8, +0x1FB => 0x1FA, +0x1FD => 0x1FC, +0x1FF => 0x1FE, +0x201 => 0x200, +0x203 => 0x202, +0x205 => 0x204, +0x207 => 0x206, +0x209 => 0x208, +0x20B => 0x20A, +0x20D => 0x20C, +0x20F => 0x20E, +0x211 => 0x210, +0x213 => 0x212, +0x215 => 0x214, +0x217 => 0x216, +0x219 => 0x218, +0x21B => 0x21A, +0x21D => 0x21C, +0x21F => 0x21E, +0x223 => 0x222, +0x225 => 0x224, +0x227 => 0x226, +0x229 => 0x228, +0x22B => 0x22A, +0x22D => 0x22C, +0x22F => 0x22E, +0x231 => 0x230, +0x233 => 0x232, +0x23C => 0x23B, +0x23F => 0x2C7E, +0x240 => 0x2C7F, +0x242 => 0x241, +0x247 => 0x246, +0x249 => 0x248, +0x24B => 0x24A, +0x24D => 0x24C, +0x24F => 0x24E, +0x250 => 0x2C6F, +0x251 => 0x2C6D, +0x252 => 0x2C70, +0x253 => 0x181, +0x254 => 0x186, +0x256 => 0x189, +0x257 => 0x18A, +0x259 => 0x18F, +0x25B => 0x190, +0x25C => 0xA7AB, +0x260 => 0x193, +0x261 => 0xA7AC, +0x263 => 0x194, +0x265 => 0xA78D, +0x266 => 0xA7AA, +0x268 => 0x197, +0x269 => 0x196, +0x26A => 0xA7AE, +0x26B => 0x2C62, +0x26C => 0xA7AD, +0x26F => 0x19C, +0x271 => 0x2C6E, +0x272 => 0x19D, +0x275 => 0x19F, +0x27D => 0x2C64, +0x280 => 0x1A6, +0x282 => 0xA7C5, +0x283 => 0x1A9, +0x287 => 0xA7B1, +0x288 => 0x1AE, +0x289 => 0x244, +0x28A => 0x1B1, +0x28B => 0x1B2, +0x28C => 0x245, +0x292 => 0x1B7, +0x29D => 0xA7B2, +0x29E => 0xA7B0, +0x345 => 0x399, +0x371 => 0x370, +0x373 => 0x372, +0x377 => 0x376, +0x37B => 0x3FD, +0x37C => 0x3FE, +0x37D => 0x3FF, +0x3AC => 0x386, +0x3AD => 0x388, +0x3AE => 0x389, +0x3AF => 0x38A, +0x3B1 => 0x391, +0x3B2 => 0x392, +0x3B3 => 0x393, +0x3B4 => 0x394, +0x3B5 => 0x395, +0x3B6 => 0x396, +0x3B7 => 0x397, +0x3B8 => 0x398, +0x3B9 => 0x399, +0x3BA => 0x39A, +0x3BB => 0x39B, +0x3BC => 0x39C, +0x3BD => 0x39D, +0x3BE => 0x39E, +0x3BF => 0x39F, +0x3C0 => 0x3A0, +0x3C1 => 0x3A1, +0x3C2 => 0x3A3, +0x3C3 => 0x3A3, +0x3C4 => 0x3A4, +0x3C5 => 0x3A5, +0x3C6 => 0x3A6, +0x3C7 => 0x3A7, +0x3C8 => 0x3A8, +0x3C9 => 0x3A9, +0x3CA => 0x3AA, +0x3CB => 0x3AB, +0x3CC => 0x38C, +0x3CD => 0x38E, +0x3CE => 0x38F, +0x3D0 => 0x392, +0x3D1 => 0x398, +0x3D5 => 0x3A6, +0x3D6 => 0x3A0, +0x3D7 => 0x3CF, +0x3D9 => 0x3D8, +0x3DB => 0x3DA, +0x3DD => 0x3DC, +0x3DF => 0x3DE, +0x3E1 => 0x3E0, +0x3E3 => 0x3E2, +0x3E5 => 0x3E4, +0x3E7 => 0x3E6, +0x3E9 => 0x3E8, +0x3EB => 0x3EA, +0x3ED => 0x3EC, +0x3EF => 0x3EE, +0x3F0 => 0x39A, +0x3F1 => 0x3A1, +0x3F2 => 0x3F9, +0x3F3 => 0x37F, +0x3F5 => 0x395, +0x3F8 => 0x3F7, +0x3FB => 0x3FA, +0x430 => 0x410, +0x431 => 0x411, +0x432 => 0x412, +0x433 => 0x413, +0x434 => 0x414, +0x435 => 0x415, +0x436 => 0x416, +0x437 => 0x417, +0x438 => 0x418, +0x439 => 0x419, +0x43A => 0x41A, +0x43B => 0x41B, +0x43C => 0x41C, +0x43D => 0x41D, +0x43E => 0x41E, +0x43F => 0x41F, +0x440 => 0x420, +0x441 => 0x421, +0x442 => 0x422, +0x443 => 0x423, +0x444 => 0x424, +0x445 => 0x425, +0x446 => 0x426, +0x447 => 0x427, +0x448 => 0x428, +0x449 => 0x429, +0x44A => 0x42A, +0x44B => 0x42B, +0x44C => 0x42C, +0x44D => 0x42D, +0x44E => 0x42E, +0x44F => 0x42F, +0x450 => 0x400, +0x451 => 0x401, +0x452 => 0x402, +0x453 => 0x403, +0x454 => 0x404, +0x455 => 0x405, +0x456 => 0x406, +0x457 => 0x407, +0x458 => 0x408, +0x459 => 0x409, +0x45A => 0x40A, +0x45B => 0x40B, +0x45C => 0x40C, +0x45D => 0x40D, +0x45E => 0x40E, +0x45F => 0x40F, +0x461 => 0x460, +0x463 => 0x462, +0x465 => 0x464, +0x467 => 0x466, +0x469 => 0x468, +0x46B => 0x46A, +0x46D => 0x46C, +0x46F => 0x46E, +0x471 => 0x470, +0x473 => 0x472, +0x475 => 0x474, +0x477 => 0x476, +0x479 => 0x478, +0x47B => 0x47A, +0x47D => 0x47C, +0x47F => 0x47E, +0x481 => 0x480, +0x48B => 0x48A, +0x48D => 0x48C, +0x48F => 0x48E, +0x491 => 0x490, +0x493 => 0x492, +0x495 => 0x494, +0x497 => 0x496, +0x499 => 0x498, +0x49B => 0x49A, +0x49D => 0x49C, +0x49F => 0x49E, +0x4A1 => 0x4A0, +0x4A3 => 0x4A2, +0x4A5 => 0x4A4, +0x4A7 => 0x4A6, +0x4A9 => 0x4A8, +0x4AB => 0x4AA, +0x4AD => 0x4AC, +0x4AF => 0x4AE, +0x4B1 => 0x4B0, +0x4B3 => 0x4B2, +0x4B5 => 0x4B4, +0x4B7 => 0x4B6, +0x4B9 => 0x4B8, +0x4BB => 0x4BA, +0x4BD => 0x4BC, +0x4BF => 0x4BE, +0x4C2 => 0x4C1, +0x4C4 => 0x4C3, +0x4C6 => 0x4C5, +0x4C8 => 0x4C7, +0x4CA => 0x4C9, +0x4CC => 0x4CB, +0x4CE => 0x4CD, +0x4CF => 0x4C0, +0x4D1 => 0x4D0, +0x4D3 => 0x4D2, +0x4D5 => 0x4D4, +0x4D7 => 0x4D6, +0x4D9 => 0x4D8, +0x4DB => 0x4DA, +0x4DD => 0x4DC, +0x4DF => 0x4DE, +0x4E1 => 0x4E0, +0x4E3 => 0x4E2, +0x4E5 => 0x4E4, +0x4E7 => 0x4E6, +0x4E9 => 0x4E8, +0x4EB => 0x4EA, +0x4ED => 0x4EC, +0x4EF => 0x4EE, +0x4F1 => 0x4F0, +0x4F3 => 0x4F2, +0x4F5 => 0x4F4, +0x4F7 => 0x4F6, +0x4F9 => 0x4F8, +0x4FB => 0x4FA, +0x4FD => 0x4FC, +0x4FF => 0x4FE, +0x501 => 0x500, +0x503 => 0x502, +0x505 => 0x504, +0x507 => 0x506, +0x509 => 0x508, +0x50B => 0x50A, +0x50D => 0x50C, +0x50F => 0x50E, +0x511 => 0x510, +0x513 => 0x512, +0x515 => 0x514, +0x517 => 0x516, +0x519 => 0x518, +0x51B => 0x51A, +0x51D => 0x51C, +0x51F => 0x51E, +0x521 => 0x520, +0x523 => 0x522, +0x525 => 0x524, +0x527 => 0x526, +0x529 => 0x528, +0x52B => 0x52A, +0x52D => 0x52C, +0x52F => 0x52E, +0x561 => 0x531, +0x562 => 0x532, +0x563 => 0x533, +0x564 => 0x534, +0x565 => 0x535, +0x566 => 0x536, +0x567 => 0x537, +0x568 => 0x538, +0x569 => 0x539, +0x56A => 0x53A, +0x56B => 0x53B, +0x56C => 0x53C, +0x56D => 0x53D, +0x56E => 0x53E, +0x56F => 0x53F, +0x570 => 0x540, +0x571 => 0x541, +0x572 => 0x542, +0x573 => 0x543, +0x574 => 0x544, +0x575 => 0x545, +0x576 => 0x546, +0x577 => 0x547, +0x578 => 0x548, +0x579 => 0x549, +0x57A => 0x54A, +0x57B => 0x54B, +0x57C => 0x54C, +0x57D => 0x54D, +0x57E => 0x54E, +0x57F => 0x54F, +0x580 => 0x550, +0x581 => 0x551, +0x582 => 0x552, +0x583 => 0x553, +0x584 => 0x554, +0x585 => 0x555, +0x586 => 0x556, +0x10D0 => 0x1C90, +0x10D1 => 0x1C91, +0x10D2 => 0x1C92, +0x10D3 => 0x1C93, +0x10D4 => 0x1C94, +0x10D5 => 0x1C95, +0x10D6 => 0x1C96, +0x10D7 => 0x1C97, +0x10D8 => 0x1C98, +0x10D9 => 0x1C99, +0x10DA => 0x1C9A, +0x10DB => 0x1C9B, +0x10DC => 0x1C9C, +0x10DD => 0x1C9D, +0x10DE => 0x1C9E, +0x10DF => 0x1C9F, +0x10E0 => 0x1CA0, +0x10E1 => 0x1CA1, +0x10E2 => 0x1CA2, +0x10E3 => 0x1CA3, +0x10E4 => 0x1CA4, +0x10E5 => 0x1CA5, +0x10E6 => 0x1CA6, +0x10E7 => 0x1CA7, +0x10E8 => 0x1CA8, +0x10E9 => 0x1CA9, +0x10EA => 0x1CAA, +0x10EB => 0x1CAB, +0x10EC => 0x1CAC, +0x10ED => 0x1CAD, +0x10EE => 0x1CAE, +0x10EF => 0x1CAF, +0x10F0 => 0x1CB0, +0x10F1 => 0x1CB1, +0x10F2 => 0x1CB2, +0x10F3 => 0x1CB3, +0x10F4 => 0x1CB4, +0x10F5 => 0x1CB5, +0x10F6 => 0x1CB6, +0x10F7 => 0x1CB7, +0x10F8 => 0x1CB8, +0x10F9 => 0x1CB9, +0x10FA => 0x1CBA, +0x10FD => 0x1CBD, +0x10FE => 0x1CBE, +0x10FF => 0x1CBF, +0x13F8 => 0x13F0, +0x13F9 => 0x13F1, +0x13FA => 0x13F2, +0x13FB => 0x13F3, +0x13FC => 0x13F4, +0x13FD => 0x13F5, +0x1C80 => 0x412, +0x1C81 => 0x414, +0x1C82 => 0x41E, +0x1C83 => 0x421, +0x1C84 => 0x422, +0x1C85 => 0x422, +0x1C86 => 0x42A, +0x1C87 => 0x462, +0x1C88 => 0xA64A, +0x1D79 => 0xA77D, +0x1D7D => 0x2C63, +0x1D8E => 0xA7C6, +0x1E01 => 0x1E00, +0x1E03 => 0x1E02, +0x1E05 => 0x1E04, +0x1E07 => 0x1E06, +0x1E09 => 0x1E08, +0x1E0B => 0x1E0A, +0x1E0D => 0x1E0C, +0x1E0F => 0x1E0E, +0x1E11 => 0x1E10, +0x1E13 => 0x1E12, +0x1E15 => 0x1E14, +0x1E17 => 0x1E16, +0x1E19 => 0x1E18, +0x1E1B => 0x1E1A, +0x1E1D => 0x1E1C, +0x1E1F => 0x1E1E, +0x1E21 => 0x1E20, +0x1E23 => 0x1E22, +0x1E25 => 0x1E24, +0x1E27 => 0x1E26, +0x1E29 => 0x1E28, +0x1E2B => 0x1E2A, +0x1E2D => 0x1E2C, +0x1E2F => 0x1E2E, +0x1E31 => 0x1E30, +0x1E33 => 0x1E32, +0x1E35 => 0x1E34, +0x1E37 => 0x1E36, +0x1E39 => 0x1E38, +0x1E3B => 0x1E3A, +0x1E3D => 0x1E3C, +0x1E3F => 0x1E3E, +0x1E41 => 0x1E40, +0x1E43 => 0x1E42, +0x1E45 => 0x1E44, +0x1E47 => 0x1E46, +0x1E49 => 0x1E48, +0x1E4B => 0x1E4A, +0x1E4D => 0x1E4C, +0x1E4F => 0x1E4E, +0x1E51 => 0x1E50, +0x1E53 => 0x1E52, +0x1E55 => 0x1E54, +0x1E57 => 0x1E56, +0x1E59 => 0x1E58, +0x1E5B => 0x1E5A, +0x1E5D => 0x1E5C, +0x1E5F => 0x1E5E, +0x1E61 => 0x1E60, +0x1E63 => 0x1E62, +0x1E65 => 0x1E64, +0x1E67 => 0x1E66, +0x1E69 => 0x1E68, +0x1E6B => 0x1E6A, +0x1E6D => 0x1E6C, +0x1E6F => 0x1E6E, +0x1E71 => 0x1E70, +0x1E73 => 0x1E72, +0x1E75 => 0x1E74, +0x1E77 => 0x1E76, +0x1E79 => 0x1E78, +0x1E7B => 0x1E7A, +0x1E7D => 0x1E7C, +0x1E7F => 0x1E7E, +0x1E81 => 0x1E80, +0x1E83 => 0x1E82, +0x1E85 => 0x1E84, +0x1E87 => 0x1E86, +0x1E89 => 0x1E88, +0x1E8B => 0x1E8A, +0x1E8D => 0x1E8C, +0x1E8F => 0x1E8E, +0x1E91 => 0x1E90, +0x1E93 => 0x1E92, +0x1E95 => 0x1E94, +0x1E9B => 0x1E60, +0x1EA1 => 0x1EA0, +0x1EA3 => 0x1EA2, +0x1EA5 => 0x1EA4, +0x1EA7 => 0x1EA6, +0x1EA9 => 0x1EA8, +0x1EAB => 0x1EAA, +0x1EAD => 0x1EAC, +0x1EAF => 0x1EAE, +0x1EB1 => 0x1EB0, +0x1EB3 => 0x1EB2, +0x1EB5 => 0x1EB4, +0x1EB7 => 0x1EB6, +0x1EB9 => 0x1EB8, +0x1EBB => 0x1EBA, +0x1EBD => 0x1EBC, +0x1EBF => 0x1EBE, +0x1EC1 => 0x1EC0, +0x1EC3 => 0x1EC2, +0x1EC5 => 0x1EC4, +0x1EC7 => 0x1EC6, +0x1EC9 => 0x1EC8, +0x1ECB => 0x1ECA, +0x1ECD => 0x1ECC, +0x1ECF => 0x1ECE, +0x1ED1 => 0x1ED0, +0x1ED3 => 0x1ED2, +0x1ED5 => 0x1ED4, +0x1ED7 => 0x1ED6, +0x1ED9 => 0x1ED8, +0x1EDB => 0x1EDA, +0x1EDD => 0x1EDC, +0x1EDF => 0x1EDE, +0x1EE1 => 0x1EE0, +0x1EE3 => 0x1EE2, +0x1EE5 => 0x1EE4, +0x1EE7 => 0x1EE6, +0x1EE9 => 0x1EE8, +0x1EEB => 0x1EEA, +0x1EED => 0x1EEC, +0x1EEF => 0x1EEE, +0x1EF1 => 0x1EF0, +0x1EF3 => 0x1EF2, +0x1EF5 => 0x1EF4, +0x1EF7 => 0x1EF6, +0x1EF9 => 0x1EF8, +0x1EFB => 0x1EFA, +0x1EFD => 0x1EFC, +0x1EFF => 0x1EFE, +0x1F00 => 0x1F08, +0x1F01 => 0x1F09, +0x1F02 => 0x1F0A, +0x1F03 => 0x1F0B, +0x1F04 => 0x1F0C, +0x1F05 => 0x1F0D, +0x1F06 => 0x1F0E, +0x1F07 => 0x1F0F, +0x1F10 => 0x1F18, +0x1F11 => 0x1F19, +0x1F12 => 0x1F1A, +0x1F13 => 0x1F1B, +0x1F14 => 0x1F1C, +0x1F15 => 0x1F1D, +0x1F20 => 0x1F28, +0x1F21 => 0x1F29, +0x1F22 => 0x1F2A, +0x1F23 => 0x1F2B, +0x1F24 => 0x1F2C, +0x1F25 => 0x1F2D, +0x1F26 => 0x1F2E, +0x1F27 => 0x1F2F, +0x1F30 => 0x1F38, +0x1F31 => 0x1F39, +0x1F32 => 0x1F3A, +0x1F33 => 0x1F3B, +0x1F34 => 0x1F3C, +0x1F35 => 0x1F3D, +0x1F36 => 0x1F3E, +0x1F37 => 0x1F3F, +0x1F40 => 0x1F48, +0x1F41 => 0x1F49, +0x1F42 => 0x1F4A, +0x1F43 => 0x1F4B, +0x1F44 => 0x1F4C, +0x1F45 => 0x1F4D, +0x1F51 => 0x1F59, +0x1F53 => 0x1F5B, +0x1F55 => 0x1F5D, +0x1F57 => 0x1F5F, +0x1F60 => 0x1F68, +0x1F61 => 0x1F69, +0x1F62 => 0x1F6A, +0x1F63 => 0x1F6B, +0x1F64 => 0x1F6C, +0x1F65 => 0x1F6D, +0x1F66 => 0x1F6E, +0x1F67 => 0x1F6F, +0x1F70 => 0x1FBA, +0x1F71 => 0x1FBB, +0x1F72 => 0x1FC8, +0x1F73 => 0x1FC9, +0x1F74 => 0x1FCA, +0x1F75 => 0x1FCB, +0x1F76 => 0x1FDA, +0x1F77 => 0x1FDB, +0x1F78 => 0x1FF8, +0x1F79 => 0x1FF9, +0x1F7A => 0x1FEA, +0x1F7B => 0x1FEB, +0x1F7C => 0x1FFA, +0x1F7D => 0x1FFB, +0x1F80 => 0x1F88, +0x1F81 => 0x1F89, +0x1F82 => 0x1F8A, +0x1F83 => 0x1F8B, +0x1F84 => 0x1F8C, +0x1F85 => 0x1F8D, +0x1F86 => 0x1F8E, +0x1F87 => 0x1F8F, +0x1F90 => 0x1F98, +0x1F91 => 0x1F99, +0x1F92 => 0x1F9A, +0x1F93 => 0x1F9B, +0x1F94 => 0x1F9C, +0x1F95 => 0x1F9D, +0x1F96 => 0x1F9E, +0x1F97 => 0x1F9F, +0x1FA0 => 0x1FA8, +0x1FA1 => 0x1FA9, +0x1FA2 => 0x1FAA, +0x1FA3 => 0x1FAB, +0x1FA4 => 0x1FAC, +0x1FA5 => 0x1FAD, +0x1FA6 => 0x1FAE, +0x1FA7 => 0x1FAF, +0x1FB0 => 0x1FB8, +0x1FB1 => 0x1FB9, +0x1FB3 => 0x1FBC, +0x1FBE => 0x399, +0x1FC3 => 0x1FCC, +0x1FD0 => 0x1FD8, +0x1FD1 => 0x1FD9, +0x1FE0 => 0x1FE8, +0x1FE1 => 0x1FE9, +0x1FE5 => 0x1FEC, +0x1FF3 => 0x1FFC, +0x214E => 0x2132, +0x2170 => 0x2160, +0x2171 => 0x2161, +0x2172 => 0x2162, +0x2173 => 0x2163, +0x2174 => 0x2164, +0x2175 => 0x2165, +0x2176 => 0x2166, +0x2177 => 0x2167, +0x2178 => 0x2168, +0x2179 => 0x2169, +0x217A => 0x216A, +0x217B => 0x216B, +0x217C => 0x216C, +0x217D => 0x216D, +0x217E => 0x216E, +0x217F => 0x216F, +0x2184 => 0x2183, +0x24D0 => 0x24B6, +0x24D1 => 0x24B7, +0x24D2 => 0x24B8, +0x24D3 => 0x24B9, +0x24D4 => 0x24BA, +0x24D5 => 0x24BB, +0x24D6 => 0x24BC, +0x24D7 => 0x24BD, +0x24D8 => 0x24BE, +0x24D9 => 0x24BF, +0x24DA => 0x24C0, +0x24DB => 0x24C1, +0x24DC => 0x24C2, +0x24DD => 0x24C3, +0x24DE => 0x24C4, +0x24DF => 0x24C5, +0x24E0 => 0x24C6, +0x24E1 => 0x24C7, +0x24E2 => 0x24C8, +0x24E3 => 0x24C9, +0x24E4 => 0x24CA, +0x24E5 => 0x24CB, +0x24E6 => 0x24CC, +0x24E7 => 0x24CD, +0x24E8 => 0x24CE, +0x24E9 => 0x24CF, +0x2C30 => 0x2C00, +0x2C31 => 0x2C01, +0x2C32 => 0x2C02, +0x2C33 => 0x2C03, +0x2C34 => 0x2C04, +0x2C35 => 0x2C05, +0x2C36 => 0x2C06, +0x2C37 => 0x2C07, +0x2C38 => 0x2C08, +0x2C39 => 0x2C09, +0x2C3A => 0x2C0A, +0x2C3B => 0x2C0B, +0x2C3C => 0x2C0C, +0x2C3D => 0x2C0D, +0x2C3E => 0x2C0E, +0x2C3F => 0x2C0F, +0x2C40 => 0x2C10, +0x2C41 => 0x2C11, +0x2C42 => 0x2C12, +0x2C43 => 0x2C13, +0x2C44 => 0x2C14, +0x2C45 => 0x2C15, +0x2C46 => 0x2C16, +0x2C47 => 0x2C17, +0x2C48 => 0x2C18, +0x2C49 => 0x2C19, +0x2C4A => 0x2C1A, +0x2C4B => 0x2C1B, +0x2C4C => 0x2C1C, +0x2C4D => 0x2C1D, +0x2C4E => 0x2C1E, +0x2C4F => 0x2C1F, +0x2C50 => 0x2C20, +0x2C51 => 0x2C21, +0x2C52 => 0x2C22, +0x2C53 => 0x2C23, +0x2C54 => 0x2C24, +0x2C55 => 0x2C25, +0x2C56 => 0x2C26, +0x2C57 => 0x2C27, +0x2C58 => 0x2C28, +0x2C59 => 0x2C29, +0x2C5A => 0x2C2A, +0x2C5B => 0x2C2B, +0x2C5C => 0x2C2C, +0x2C5D => 0x2C2D, +0x2C5E => 0x2C2E, +0x2C61 => 0x2C60, +0x2C65 => 0x23A, +0x2C66 => 0x23E, +0x2C68 => 0x2C67, +0x2C6A => 0x2C69, +0x2C6C => 0x2C6B, +0x2C73 => 0x2C72, +0x2C76 => 0x2C75, +0x2C81 => 0x2C80, +0x2C83 => 0x2C82, +0x2C85 => 0x2C84, +0x2C87 => 0x2C86, +0x2C89 => 0x2C88, +0x2C8B => 0x2C8A, +0x2C8D => 0x2C8C, +0x2C8F => 0x2C8E, +0x2C91 => 0x2C90, +0x2C93 => 0x2C92, +0x2C95 => 0x2C94, +0x2C97 => 0x2C96, +0x2C99 => 0x2C98, +0x2C9B => 0x2C9A, +0x2C9D => 0x2C9C, +0x2C9F => 0x2C9E, +0x2CA1 => 0x2CA0, +0x2CA3 => 0x2CA2, +0x2CA5 => 0x2CA4, +0x2CA7 => 0x2CA6, +0x2CA9 => 0x2CA8, +0x2CAB => 0x2CAA, +0x2CAD => 0x2CAC, +0x2CAF => 0x2CAE, +0x2CB1 => 0x2CB0, +0x2CB3 => 0x2CB2, +0x2CB5 => 0x2CB4, +0x2CB7 => 0x2CB6, +0x2CB9 => 0x2CB8, +0x2CBB => 0x2CBA, +0x2CBD => 0x2CBC, +0x2CBF => 0x2CBE, +0x2CC1 => 0x2CC0, +0x2CC3 => 0x2CC2, +0x2CC5 => 0x2CC4, +0x2CC7 => 0x2CC6, +0x2CC9 => 0x2CC8, +0x2CCB => 0x2CCA, +0x2CCD => 0x2CCC, +0x2CCF => 0x2CCE, +0x2CD1 => 0x2CD0, +0x2CD3 => 0x2CD2, +0x2CD5 => 0x2CD4, +0x2CD7 => 0x2CD6, +0x2CD9 => 0x2CD8, +0x2CDB => 0x2CDA, +0x2CDD => 0x2CDC, +0x2CDF => 0x2CDE, +0x2CE1 => 0x2CE0, +0x2CE3 => 0x2CE2, +0x2CEC => 0x2CEB, +0x2CEE => 0x2CED, +0x2CF3 => 0x2CF2, +0x2D00 => 0x10A0, +0x2D01 => 0x10A1, +0x2D02 => 0x10A2, +0x2D03 => 0x10A3, +0x2D04 => 0x10A4, +0x2D05 => 0x10A5, +0x2D06 => 0x10A6, +0x2D07 => 0x10A7, +0x2D08 => 0x10A8, +0x2D09 => 0x10A9, +0x2D0A => 0x10AA, +0x2D0B => 0x10AB, +0x2D0C => 0x10AC, +0x2D0D => 0x10AD, +0x2D0E => 0x10AE, +0x2D0F => 0x10AF, +0x2D10 => 0x10B0, +0x2D11 => 0x10B1, +0x2D12 => 0x10B2, +0x2D13 => 0x10B3, +0x2D14 => 0x10B4, +0x2D15 => 0x10B5, +0x2D16 => 0x10B6, +0x2D17 => 0x10B7, +0x2D18 => 0x10B8, +0x2D19 => 0x10B9, +0x2D1A => 0x10BA, +0x2D1B => 0x10BB, +0x2D1C => 0x10BC, +0x2D1D => 0x10BD, +0x2D1E => 0x10BE, +0x2D1F => 0x10BF, +0x2D20 => 0x10C0, +0x2D21 => 0x10C1, +0x2D22 => 0x10C2, +0x2D23 => 0x10C3, +0x2D24 => 0x10C4, +0x2D25 => 0x10C5, +0x2D27 => 0x10C7, +0x2D2D => 0x10CD, +0xA641 => 0xA640, +0xA643 => 0xA642, +0xA645 => 0xA644, +0xA647 => 0xA646, +0xA649 => 0xA648, +0xA64B => 0xA64A, +0xA64D => 0xA64C, +0xA64F => 0xA64E, +0xA651 => 0xA650, +0xA653 => 0xA652, +0xA655 => 0xA654, +0xA657 => 0xA656, +0xA659 => 0xA658, +0xA65B => 0xA65A, +0xA65D => 0xA65C, +0xA65F => 0xA65E, +0xA661 => 0xA660, +0xA663 => 0xA662, +0xA665 => 0xA664, +0xA667 => 0xA666, +0xA669 => 0xA668, +0xA66B => 0xA66A, +0xA66D => 0xA66C, +0xA681 => 0xA680, +0xA683 => 0xA682, +0xA685 => 0xA684, +0xA687 => 0xA686, +0xA689 => 0xA688, +0xA68B => 0xA68A, +0xA68D => 0xA68C, +0xA68F => 0xA68E, +0xA691 => 0xA690, +0xA693 => 0xA692, +0xA695 => 0xA694, +0xA697 => 0xA696, +0xA699 => 0xA698, +0xA69B => 0xA69A, +0xA723 => 0xA722, +0xA725 => 0xA724, +0xA727 => 0xA726, +0xA729 => 0xA728, +0xA72B => 0xA72A, +0xA72D => 0xA72C, +0xA72F => 0xA72E, +0xA733 => 0xA732, +0xA735 => 0xA734, +0xA737 => 0xA736, +0xA739 => 0xA738, +0xA73B => 0xA73A, +0xA73D => 0xA73C, +0xA73F => 0xA73E, +0xA741 => 0xA740, +0xA743 => 0xA742, +0xA745 => 0xA744, +0xA747 => 0xA746, +0xA749 => 0xA748, +0xA74B => 0xA74A, +0xA74D => 0xA74C, +0xA74F => 0xA74E, +0xA751 => 0xA750, +0xA753 => 0xA752, +0xA755 => 0xA754, +0xA757 => 0xA756, +0xA759 => 0xA758, +0xA75B => 0xA75A, +0xA75D => 0xA75C, +0xA75F => 0xA75E, +0xA761 => 0xA760, +0xA763 => 0xA762, +0xA765 => 0xA764, +0xA767 => 0xA766, +0xA769 => 0xA768, +0xA76B => 0xA76A, +0xA76D => 0xA76C, +0xA76F => 0xA76E, +0xA77A => 0xA779, +0xA77C => 0xA77B, +0xA77F => 0xA77E, +0xA781 => 0xA780, +0xA783 => 0xA782, +0xA785 => 0xA784, +0xA787 => 0xA786, +0xA78C => 0xA78B, +0xA791 => 0xA790, +0xA793 => 0xA792, +0xA794 => 0xA7C4, +0xA797 => 0xA796, +0xA799 => 0xA798, +0xA79B => 0xA79A, +0xA79D => 0xA79C, +0xA79F => 0xA79E, +0xA7A1 => 0xA7A0, +0xA7A3 => 0xA7A2, +0xA7A5 => 0xA7A4, +0xA7A7 => 0xA7A6, +0xA7A9 => 0xA7A8, +0xA7B5 => 0xA7B4, +0xA7B7 => 0xA7B6, +0xA7B9 => 0xA7B8, +0xA7BB => 0xA7BA, +0xA7BD => 0xA7BC, +0xA7BF => 0xA7BE, +0xA7C3 => 0xA7C2, +0xA7C8 => 0xA7C7, +0xA7CA => 0xA7C9, +0xA7F6 => 0xA7F5, +0xAB53 => 0xA7B3, +0xAB70 => 0x13A0, +0xAB71 => 0x13A1, +0xAB72 => 0x13A2, +0xAB73 => 0x13A3, +0xAB74 => 0x13A4, +0xAB75 => 0x13A5, +0xAB76 => 0x13A6, +0xAB77 => 0x13A7, +0xAB78 => 0x13A8, +0xAB79 => 0x13A9, +0xAB7A => 0x13AA, +0xAB7B => 0x13AB, +0xAB7C => 0x13AC, +0xAB7D => 0x13AD, +0xAB7E => 0x13AE, +0xAB7F => 0x13AF, +0xAB80 => 0x13B0, +0xAB81 => 0x13B1, +0xAB82 => 0x13B2, +0xAB83 => 0x13B3, +0xAB84 => 0x13B4, +0xAB85 => 0x13B5, +0xAB86 => 0x13B6, +0xAB87 => 0x13B7, +0xAB88 => 0x13B8, +0xAB89 => 0x13B9, +0xAB8A => 0x13BA, +0xAB8B => 0x13BB, +0xAB8C => 0x13BC, +0xAB8D => 0x13BD, +0xAB8E => 0x13BE, +0xAB8F => 0x13BF, +0xAB90 => 0x13C0, +0xAB91 => 0x13C1, +0xAB92 => 0x13C2, +0xAB93 => 0x13C3, +0xAB94 => 0x13C4, +0xAB95 => 0x13C5, +0xAB96 => 0x13C6, +0xAB97 => 0x13C7, +0xAB98 => 0x13C8, +0xAB99 => 0x13C9, +0xAB9A => 0x13CA, +0xAB9B => 0x13CB, +0xAB9C => 0x13CC, +0xAB9D => 0x13CD, +0xAB9E => 0x13CE, +0xAB9F => 0x13CF, +0xABA0 => 0x13D0, +0xABA1 => 0x13D1, +0xABA2 => 0x13D2, +0xABA3 => 0x13D3, +0xABA4 => 0x13D4, +0xABA5 => 0x13D5, +0xABA6 => 0x13D6, +0xABA7 => 0x13D7, +0xABA8 => 0x13D8, +0xABA9 => 0x13D9, +0xABAA => 0x13DA, +0xABAB => 0x13DB, +0xABAC => 0x13DC, +0xABAD => 0x13DD, +0xABAE => 0x13DE, +0xABAF => 0x13DF, +0xABB0 => 0x13E0, +0xABB1 => 0x13E1, +0xABB2 => 0x13E2, +0xABB3 => 0x13E3, +0xABB4 => 0x13E4, +0xABB5 => 0x13E5, +0xABB6 => 0x13E6, +0xABB7 => 0x13E7, +0xABB8 => 0x13E8, +0xABB9 => 0x13E9, +0xABBA => 0x13EA, +0xABBB => 0x13EB, +0xABBC => 0x13EC, +0xABBD => 0x13ED, +0xABBE => 0x13EE, +0xABBF => 0x13EF, +0xFF41 => 0xFF21, +0xFF42 => 0xFF22, +0xFF43 => 0xFF23, +0xFF44 => 0xFF24, +0xFF45 => 0xFF25, +0xFF46 => 0xFF26, +0xFF47 => 0xFF27, +0xFF48 => 0xFF28, +0xFF49 => 0xFF29, +0xFF4A => 0xFF2A, +0xFF4B => 0xFF2B, +0xFF4C => 0xFF2C, +0xFF4D => 0xFF2D, +0xFF4E => 0xFF2E, +0xFF4F => 0xFF2F, +0xFF50 => 0xFF30, +0xFF51 => 0xFF31, +0xFF52 => 0xFF32, +0xFF53 => 0xFF33, +0xFF54 => 0xFF34, +0xFF55 => 0xFF35, +0xFF56 => 0xFF36, +0xFF57 => 0xFF37, +0xFF58 => 0xFF38, +0xFF59 => 0xFF39, +0xFF5A => 0xFF3A, +0x10428 => 0x10400, +0x10429 => 0x10401, +0x1042A => 0x10402, +0x1042B => 0x10403, +0x1042C => 0x10404, +0x1042D => 0x10405, +0x1042E => 0x10406, +0x1042F => 0x10407, +0x10430 => 0x10408, +0x10431 => 0x10409, +0x10432 => 0x1040A, +0x10433 => 0x1040B, +0x10434 => 0x1040C, +0x10435 => 0x1040D, +0x10436 => 0x1040E, +0x10437 => 0x1040F, +0x10438 => 0x10410, +0x10439 => 0x10411, +0x1043A => 0x10412, +0x1043B => 0x10413, +0x1043C => 0x10414, +0x1043D => 0x10415, +0x1043E => 0x10416, +0x1043F => 0x10417, +0x10440 => 0x10418, +0x10441 => 0x10419, +0x10442 => 0x1041A, +0x10443 => 0x1041B, +0x10444 => 0x1041C, +0x10445 => 0x1041D, +0x10446 => 0x1041E, +0x10447 => 0x1041F, +0x10448 => 0x10420, +0x10449 => 0x10421, +0x1044A => 0x10422, +0x1044B => 0x10423, +0x1044C => 0x10424, +0x1044D => 0x10425, +0x1044E => 0x10426, +0x1044F => 0x10427, +0x104D8 => 0x104B0, +0x104D9 => 0x104B1, +0x104DA => 0x104B2, +0x104DB => 0x104B3, +0x104DC => 0x104B4, +0x104DD => 0x104B5, +0x104DE => 0x104B6, +0x104DF => 0x104B7, +0x104E0 => 0x104B8, +0x104E1 => 0x104B9, +0x104E2 => 0x104BA, +0x104E3 => 0x104BB, +0x104E4 => 0x104BC, +0x104E5 => 0x104BD, +0x104E6 => 0x104BE, +0x104E7 => 0x104BF, +0x104E8 => 0x104C0, +0x104E9 => 0x104C1, +0x104EA => 0x104C2, +0x104EB => 0x104C3, +0x104EC => 0x104C4, +0x104ED => 0x104C5, +0x104EE => 0x104C6, +0x104EF => 0x104C7, +0x104F0 => 0x104C8, +0x104F1 => 0x104C9, +0x104F2 => 0x104CA, +0x104F3 => 0x104CB, +0x104F4 => 0x104CC, +0x104F5 => 0x104CD, +0x104F6 => 0x104CE, +0x104F7 => 0x104CF, +0x104F8 => 0x104D0, +0x104F9 => 0x104D1, +0x104FA => 0x104D2, +0x104FB => 0x104D3, +0x10CC0 => 0x10C80, +0x10CC1 => 0x10C81, +0x10CC2 => 0x10C82, +0x10CC3 => 0x10C83, +0x10CC4 => 0x10C84, +0x10CC5 => 0x10C85, +0x10CC6 => 0x10C86, +0x10CC7 => 0x10C87, +0x10CC8 => 0x10C88, +0x10CC9 => 0x10C89, +0x10CCA => 0x10C8A, +0x10CCB => 0x10C8B, +0x10CCC => 0x10C8C, +0x10CCD => 0x10C8D, +0x10CCE => 0x10C8E, +0x10CCF => 0x10C8F, +0x10CD0 => 0x10C90, +0x10CD1 => 0x10C91, +0x10CD2 => 0x10C92, +0x10CD3 => 0x10C93, +0x10CD4 => 0x10C94, +0x10CD5 => 0x10C95, +0x10CD6 => 0x10C96, +0x10CD7 => 0x10C97, +0x10CD8 => 0x10C98, +0x10CD9 => 0x10C99, +0x10CDA => 0x10C9A, +0x10CDB => 0x10C9B, +0x10CDC => 0x10C9C, +0x10CDD => 0x10C9D, +0x10CDE => 0x10C9E, +0x10CDF => 0x10C9F, +0x10CE0 => 0x10CA0, +0x10CE1 => 0x10CA1, +0x10CE2 => 0x10CA2, +0x10CE3 => 0x10CA3, +0x10CE4 => 0x10CA4, +0x10CE5 => 0x10CA5, +0x10CE6 => 0x10CA6, +0x10CE7 => 0x10CA7, +0x10CE8 => 0x10CA8, +0x10CE9 => 0x10CA9, +0x10CEA => 0x10CAA, +0x10CEB => 0x10CAB, +0x10CEC => 0x10CAC, +0x10CED => 0x10CAD, +0x10CEE => 0x10CAE, +0x10CEF => 0x10CAF, +0x10CF0 => 0x10CB0, +0x10CF1 => 0x10CB1, +0x10CF2 => 0x10CB2, +0x118C0 => 0x118A0, +0x118C1 => 0x118A1, +0x118C2 => 0x118A2, +0x118C3 => 0x118A3, +0x118C4 => 0x118A4, +0x118C5 => 0x118A5, +0x118C6 => 0x118A6, +0x118C7 => 0x118A7, +0x118C8 => 0x118A8, +0x118C9 => 0x118A9, +0x118CA => 0x118AA, +0x118CB => 0x118AB, +0x118CC => 0x118AC, +0x118CD => 0x118AD, +0x118CE => 0x118AE, +0x118CF => 0x118AF, +0x118D0 => 0x118B0, +0x118D1 => 0x118B1, +0x118D2 => 0x118B2, +0x118D3 => 0x118B3, +0x118D4 => 0x118B4, +0x118D5 => 0x118B5, +0x118D6 => 0x118B6, +0x118D7 => 0x118B7, +0x118D8 => 0x118B8, +0x118D9 => 0x118B9, +0x118DA => 0x118BA, +0x118DB => 0x118BB, +0x118DC => 0x118BC, +0x118DD => 0x118BD, +0x118DE => 0x118BE, +0x118DF => 0x118BF, +0x16E60 => 0x16E40, +0x16E61 => 0x16E41, +0x16E62 => 0x16E42, +0x16E63 => 0x16E43, +0x16E64 => 0x16E44, +0x16E65 => 0x16E45, +0x16E66 => 0x16E46, +0x16E67 => 0x16E47, +0x16E68 => 0x16E48, +0x16E69 => 0x16E49, +0x16E6A => 0x16E4A, +0x16E6B => 0x16E4B, +0x16E6C => 0x16E4C, +0x16E6D => 0x16E4D, +0x16E6E => 0x16E4E, +0x16E6F => 0x16E4F, +0x16E70 => 0x16E50, +0x16E71 => 0x16E51, +0x16E72 => 0x16E52, +0x16E73 => 0x16E53, +0x16E74 => 0x16E54, +0x16E75 => 0x16E55, +0x16E76 => 0x16E56, +0x16E77 => 0x16E57, +0x16E78 => 0x16E58, +0x16E79 => 0x16E59, +0x16E7A => 0x16E5A, +0x16E7B => 0x16E5B, +0x16E7C => 0x16E5C, +0x16E7D => 0x16E5D, +0x16E7E => 0x16E5E, +0x16E7F => 0x16E5F, +0x1E922 => 0x1E900, +0x1E923 => 0x1E901, +0x1E924 => 0x1E902, +0x1E925 => 0x1E903, +0x1E926 => 0x1E904, +0x1E927 => 0x1E905, +0x1E928 => 0x1E906, +0x1E929 => 0x1E907, +0x1E92A => 0x1E908, +0x1E92B => 0x1E909, +0x1E92C => 0x1E90A, +0x1E92D => 0x1E90B, +0x1E92E => 0x1E90C, +0x1E92F => 0x1E90D, +0x1E930 => 0x1E90E, +0x1E931 => 0x1E90F, +0x1E932 => 0x1E910, +0x1E933 => 0x1E911, +0x1E934 => 0x1E912, +0x1E935 => 0x1E913, +0x1E936 => 0x1E914, +0x1E937 => 0x1E915, +0x1E938 => 0x1E916, +0x1E939 => 0x1E917, +0x1E93A => 0x1E918, +0x1E93B => 0x1E919, +0x1E93C => 0x1E91A, +0x1E93D => 0x1E91B, +0x1E93E => 0x1E91C, +0x1E93F => 0x1E91D, +0x1E940 => 0x1E91E, +0x1E941 => 0x1E91F, +0x1E942 => 0x1E920, +0x1E943 => 0x1E921, +]; diff --git a/vendor/opis/string/src/Exception/InvalidCodePointException.php b/vendor/opis/string/src/Exception/InvalidCodePointException.php new file mode 100644 index 0000000..f1a3fe9 --- /dev/null +++ b/vendor/opis/string/src/Exception/InvalidCodePointException.php @@ -0,0 +1,46 @@ +codePoint = $codePoint; + } + + /** + * @return mixed + */ + public function codePoint() + { + return$this->codePoint; + } +} diff --git a/vendor/opis/string/src/Exception/InvalidStringException.php b/vendor/opis/string/src/Exception/InvalidStringException.php new file mode 100644 index 0000000..11e52dd --- /dev/null +++ b/vendor/opis/string/src/Exception/InvalidStringException.php @@ -0,0 +1,61 @@ +string = $string; + $this->offset = $offset; + } + + /** + * @return string + */ + public function string(): string + { + return $this->string; + } + + /** + * @return int + */ + public function offset(): int + { + return $this->offset; + } +} diff --git a/vendor/opis/string/src/Exception/UnicodeException.php b/vendor/opis/string/src/Exception/UnicodeException.php new file mode 100644 index 0000000..22e6d2f --- /dev/null +++ b/vendor/opis/string/src/Exception/UnicodeException.php @@ -0,0 +1,25 @@ +codes = $codes; + $this->length = count($codes); + } + + /** + * @return int[] + */ + public function codePoints(): array + { + return $this->codes; + } + + /** + * @return string[] + */ + public function chars(): array + { + if ($this->chars === null) { + $this->chars = self::getCharsFromCodePoints($this->codes); + } + return $this->chars; + } + + /** + * @return int + */ + public function length(): int + { + return $this->length; + } + + /** + * @return bool + */ + public function isEmpty(): bool + { + return $this->length === 0; + } + + /** + * @param string|self|int[]|string[] $text + * @param bool $ignoreCase + * @return bool + */ + public function equals($text, bool $ignoreCase = false): bool + { + return $this->compareTo($text, $ignoreCase) === 0; + } + + /** + * @param string|self|int[]|string[] $text + * @param bool $ignoreCase + * @return int + */ + public function compareTo($text, bool $ignoreCase = false): int + { + $mode = $ignoreCase ? self::FOLD_CASE : self::KEEP_CASE; + + $text = self::resolveCodePoints($text, $mode); + + $length = count($text); + + if ($length !== $this->length) { + return $this->length <=> $length; + } + + return $this->getMappedCodes($mode) <=> $text; + } + + /** + * @param string|self|int[]|string[] $text + * @param bool $ignoreCase + * @return bool + */ + public function contains($text, bool $ignoreCase = false): bool + { + return $this->indexOf($text, 0, $ignoreCase) !== -1; + } + + /** + * @param string|self|int[]|string[] $text + * @param bool $ignoreCase + * @return bool + */ + public function startsWith($text, bool $ignoreCase = false): bool + { + $mode = $ignoreCase ? self::FOLD_CASE : self::KEEP_CASE; + + $text = self::resolveCodePoints($text, $mode); + + $len = count($text); + + if ($len === 0 || $len > $this->length) { + return false; + } + + return array_slice($this->getMappedCodes($mode), 0, $len) === $text; + } + + /** + * @param string|self|int[]|string[] $text + * @param bool $ignoreCase + * @return bool + */ + public function endsWith($text, bool $ignoreCase = false): bool + { + $mode = $ignoreCase ? self::FOLD_CASE : self::KEEP_CASE; + + $text = self::resolveCodePoints($text, $mode); + + if (empty($text)) { + return false; + } + + $codes = $this->getMappedCodes($mode); + + $offset = $this->length - count($text); + + if ($offset < 0) { + return false; + } + + return array_slice($codes, $offset) === $text; + } + + /** + * @param string|self|int[]|string[] $text + * @param int $offset + * @param bool $ignoreCase + * @return int + */ + public function indexOf($text, int $offset = 0, bool $ignoreCase = false): int + { + if ($offset < 0) { + $offset += $this->length; + } + if ($offset < 0 || $offset >= $this->length) { + return -1; + } + + $mode = $ignoreCase ? self::FOLD_CASE : self::KEEP_CASE; + + $text = self::resolveCodePoints($text, $mode); + + $len = count($text); + + if ($len === 0 || $offset + $len > $this->length) { + return -1; + } + + return $this->doIndexOf($this->getMappedCodes($mode), $text, $offset); + } + + /** + * @param string|self|int[]|string[] $text + * @param int $offset + * @param bool $ignoreCase + * @return int + */ + public function lastIndexOf($text, int $offset = 0, bool $ignoreCase = false): int + { + if ($offset < 0) { + $start = $this->length + $offset; + if ($start < 0) { + return -1; + } + $last = 0; + } else { + if ($offset >= $this->length) { + return -1; + } + $start = $this->length - 1; + $last = $offset; + } + + $mode = $ignoreCase ? self::FOLD_CASE : self::KEEP_CASE; + + $text = self::resolveCodePoints($text, $mode); + + $len = count($text); + + if ($len === 0) { + return -1; + } + + if ($offset < 0) { + if ($len > $this->length) { + return -1; + } + $start = min($start, $this->length - $len); + } elseif ($offset + $len > $this->length) { + return -1; + } + + $codes = $this->getMappedCodes($mode); + + for ($i = $start; $i >= $last; $i--) { + $match = true; + + for ($j = 0; $j < $len; $j++) { + if ($codes[$i + $j] !== $text[$j]) { + $match = false; + break; + } + } + + if ($match) { + return $i; + } + } + + return -1; + } + + /** + * @param string|self|int[]|string[] $text + * @param bool $ignoreCase + * @param bool $allowPrefixOnly If true the result can contain only the prefix + * @return $this + */ + public function ensurePrefix($text, bool $ignoreCase = false, bool $allowPrefixOnly = true): self + { + $text = self::resolveCodePoints($text); + + $len = count($text); + + if ($len === 0) { + return clone $this; + } + + if ($this->length === 0) { + return new static($text); + } + + if ($ignoreCase) { + $prefix = self::getMappedCodePoints($text, self::FOLD_CASE); + } else { + $prefix = &$text; + } + + if ($this->length === $len) { + $part = $this->getMappedCodes($ignoreCase ? self::FOLD_CASE : self::KEEP_CASE); + if ($allowPrefixOnly && $part === $prefix) { + return clone $this; + } + // Remove last element to avoid double check + array_pop($part); + } elseif ($this->length < $len) { + $part = $this->getMappedCodes($ignoreCase ? self::FOLD_CASE : self::KEEP_CASE); + // Checks if this can be a suffix + if ($allowPrefixOnly && (array_slice($prefix, 0, $this->length) === $part)) { + $text = array_slice($text, $this->length); + return new static(array_merge($this->codes, $text)); + } + } else { + $part = array_slice($this->codes, 0, $len); + if ($ignoreCase) { + $part = self::getMappedCodePoints($part, self::FOLD_CASE); + } + if ($part === $prefix) { + return clone $this; + } + // Remove last element to avoid double check + array_pop($part); + } + + $copy = $len; + + $part_len = count($part); + + while ($part_len) { + if ($part === array_slice($prefix, -$part_len)) { + $copy = $len - $part_len; + break; + } + array_pop($part); + $part_len--; + } + + if ($copy === 0) { + return clone $this; + } + + if ($copy < $len) { + $text = array_slice($text, 0, $copy); + } + + return new static(array_merge($text, $this->codes)); + } + + /** + * @param string|self|int[]|string[] $text + * @param bool $ignoreCase + * @param bool $allowSuffixOnly If true the result can contain only the suffix + * @return static + */ + public function ensureSuffix($text, bool $ignoreCase = false, bool $allowSuffixOnly = true): self + { + $text = self::resolveCodePoints($text); + + $len = count($text); + + if ($len === 0) { + return clone $this; + } + + if ($this->length === 0) { + return new static($text); + } + + if ($ignoreCase) { + $suffix = self::getMappedCodePoints($text, self::FOLD_CASE); + } else { + $suffix = &$text; + } + + if ($this->length === $len) { + $part = $this->getMappedCodes($ignoreCase ? self::FOLD_CASE : self::KEEP_CASE); + if ($allowSuffixOnly && $part === $suffix) { + return clone $this; + } + // Remove first element to avoid double check + array_shift($part); + } elseif ($this->length < $len) { + $part = $this->getMappedCodes($ignoreCase ? self::FOLD_CASE : self::KEEP_CASE); + // Checks if this can be a prefix + if ($allowSuffixOnly && (array_slice($suffix, -$this->length) === $part)) { + $text = array_slice($text, 0, $len - $this->length); + return new static(array_merge($text, $this->codes)); + } + } else { + $part = array_slice($this->codes, -$len); + if ($ignoreCase) { + $part = self::getMappedCodePoints($part, self::FOLD_CASE); + } + if ($part === $suffix) { + return clone $this; + } + // Remove first element to avoid double check + array_shift($part); + } + + $skip = 0; + + $part_len = count($part); + + while ($part_len) { + if ($part === array_slice($suffix, 0, $part_len)) { + $skip = $part_len; + break; + } + array_shift($part); + $part_len--; + } + + if ($skip === $len) { + return clone $this; + } + + if ($skip) { + array_splice($text, 0, $skip); + } + + return new static(array_merge($this->codes, $text)); + } + + /** + * @param string|self|int[]|string[] $text + * @param int $mode + * @return static + */ + public function append($text, int $mode = self::KEEP_CASE): self + { + return new static(array_merge($this->codes, self::resolveCodePoints($text, $mode))); + } + + /** + * @param string|self|int[]|string[] $text + * @param int $mode + * @return static + */ + public function prepend($text, int $mode = self::KEEP_CASE): self + { + return new static(array_merge(self::resolveCodePoints($text, $mode), $this->codes)); + } + + /** + * @param string|self|int[]|string[] $text + * @param int $offset + * @param int $mode + * @return static + */ + public function insert($text, int $offset, int $mode = self::KEEP_CASE): self + { + $codes = $this->codes; + + array_splice($codes, $offset, 0, self::resolveCodePoints($text, $mode)); + + return new static($codes); + } + + /** + * @param int $offset + * @param int|null $length + * @return static + */ + public function remove(int $offset, ?int $length = null): self + { + $codes = $this->codes; + + if ($length === null) { + array_splice($codes, $offset); + } else { + array_splice($codes, $offset, $length); + } + + return new static($codes); + } + + /** + * @param string|self|int[]|string[] $mask + * @return static + */ + public function trim($mask = " \t\n\r\0\x0B"): self + { + return $this->doTrim($mask, true, true); + } + + /** + * @param string|self|int[]|string[] $mask + * @return static + */ + public function trimLeft($mask = " \t\n\r\0\x0B"): self + { + return $this->doTrim($mask, true, false); + } + + /** + * @param string|self|int[]|string[] $mask + * @return static + */ + public function trimRight($mask = " \t\n\r\0\x0B"): self + { + return $this->doTrim($mask, false, true); + } + + /** + * @return static + */ + public function reverse(): self + { + return new static(array_reverse($this->codes)); + } + + /** + * @param int $times + * @return static + */ + public function repeat(int $times = 1): self + { + if ($times <= 1) { + return clone $this; + } + + $codes = []; + + while ($times--) { + $codes = array_merge($codes, $this->codes); + } + + return new static($codes); + } + + /** + * @param string|self|int[]|string[] $subject + * @param string|self|int[]|string[] $replace + * @param int $offset + * @param bool $ignoreCase + * @return static + */ + public function replace($subject, $replace, int $offset = 0, bool $ignoreCase = false): self + { + if ($offset < 0) { + $offset += $this->length; + } + if ($offset < 0 || $offset >= $this->length) { + return clone $this; + } + + $mode = $ignoreCase ? self::FOLD_CASE : self::KEEP_CASE; + + $subject = self::resolveCodePoints($subject, $mode); + + $len = count($subject); + + if ($len === 0 || $offset + $len > $this->length) { + return clone $this; + } + + $offset = $this->doIndexOf($this->getMappedCodes($mode), $subject, $offset); + + if ($offset === -1) { + return clone $this; + } + + $codes = $this->codes; + + array_splice($codes, $offset, count($subject), self::resolveCodePoints($replace)); + + return new static($codes); + } + + /** + * @param string|self|int[]|string[] $subject + * @param string|self|int[]|string[] $replace + * @param bool $ignoreCase + * @param int $offset + * @return static + */ + public function replaceAll($subject, $replace, int $offset = 0, bool $ignoreCase = false): self + { + if ($offset < 0) { + $offset += $this->length; + } + if ($offset < 0 || $offset >= $this->length) { + return clone $this; + } + + $mode = $ignoreCase ? self::FOLD_CASE : self::KEEP_CASE; + + $subject = self::resolveCodePoints($subject, $mode); + + $len = count($subject); + + if ($len === 0 || $offset + $len > $this->length) { + return clone $this; + } + + $replace = self::resolveCodePoints($replace); + + $codes = $this->getMappedCodes($mode); + + $copy = $this->codes; + + $fix = count($replace) - $len; + + $t = 0; + + while (($pos = $this->doIndexOf($codes, $subject, $offset)) >= 0) { + array_splice($copy, $pos + $t * $fix, $len, $replace); + $offset = $pos + $len; + $t++; + } + + return new static($copy); + } + + /** + * @param string|self|int[]|string[] $delimiter + * @param bool $ignoreCase + * @return array + */ + public function split($delimiter = '', bool $ignoreCase = false): array + { + $mode = $ignoreCase ? self::FOLD_CASE : self::KEEP_CASE; + $delimiter = self::resolveCodePoints($delimiter, $mode); + $len = count($delimiter); + + $ret = []; + + if ($len === 0) { + foreach ($this->codes as $code) { + $ret[] = new static([$code]); + } + } else { + $codes = $this->getMappedCodes($mode); + + $offset = 0; + + while (($pos = $this->doIndexOf($codes, $delimiter, $offset)) >= 0) { + $ret[] = new static(array_slice($this->codes, $offset, $pos - $offset)); + $offset = $pos + $len; + } + + $ret[] = new static(array_slice($this->codes, $offset)); + } + + return $ret; + } + + /** + * @param int $start + * @param int|null $length + * @return static + */ + public function substring(int $start, ?int $length = null): self + { + return new static(array_slice($this->codes, $start, $length)); + } + + /** + * @param int $size If negative then pad left otherwise pad right + * @param self|string|int $char A char or a code point + * @return static + */ + public function pad(int $size, $char = 0x20): self + { + return new static(array_pad($this->codes, $size, self::resolveFirstCodePoint($char, 0x20))); + } + + /** + * @param int $size + * @param self|string|int $char + * @return static + */ + public function padLeft(int $size, $char = 0x20): self + { + if ($size > 0) { + $size = -$size; + } + + return $this->pad($size, $char); + } + + /** + * @param int $size + * @param self|string|int $char + * @return static + */ + public function padRight(int $size, $char = 0x20): self + { + if ($size < 0) { + $size = -$size; + } + + return $this->pad($size, $char); + } + + /** + * @return bool + */ + public function isLowerCase(): bool + { + return $this->isCase(self::LOWER_CASE); + } + + /** + * @return bool + */ + public function isUpperCase(): bool + { + return $this->isCase(self::UPPER_CASE); + } + + /** + * @return bool + */ + public function isAscii(): bool + { + $key = 'i' . self::ASCII_CONV; + + if (!isset($this->cache[$key])) { + $ok = true; + + foreach ($this->codes as $code) { + if ($code >= 0x80) { + $ok = false; + break; + } + } + + $this->cache[$key] = $ok; + } + + return $this->cache[$key]; + } + + /** + * Convert all chars to lower case (where possible) + * @return static + */ + public function toLower(): self + { + if ($this->cache['i' . self::LOWER_CASE] ?? false) { + return clone $this; + } + return new static($this->getMappedCodes(self::LOWER_CASE)); + } + + /** + * Convert all chars to upper case (where possible) + * @return static + */ + public function toUpper(): self + { + if ($this->cache['i' . self::UPPER_CASE] ?? false) { + return clone $this; + } + return new static($this->getMappedCodes(self::UPPER_CASE)); + } + + /** + * Converts all chars to their ASCII equivalent (if any) + * @return static + */ + public function toAscii(): self + { + if ($this->cache['i' . self::ASCII_CONV] ?? false) { + return clone $this; + } + return new static($this->getMappedCodes(self::ASCII_CONV)); + } + + /** + * @param int $index + * @return string + */ + public function charAt(int $index): string + { + // Allow negative index + if ($index < 0 && $index + $this->length >= 0) { + $index += $this->length; + } + + if ($index < 0 || $index >= $this->length) { + return ''; + } + + return $this->chars()[$index]; + } + + /** + * @param int $index + * @return int + */ + public function codePointAt(int $index): int + { + // Allow negative index + if ($index < 0 && $index + $this->length >= 0) { + $index += $this->length; + } + + if ($index < 0 || $index >= $this->length) { + return -1; + } + + return $this->codes[$index]; + } + + /** + * @param int $offset + * @return int + */ + public function __invoke(int $offset): int + { + if ($offset < 0) { + if ($offset + $this->length < 0) { + throw new OutOfBoundsException("Undefined offset: {$offset}"); + } + $offset += $this->length; + } elseif ($offset >= $this->length) { + throw new OutOfBoundsException("Undefined offset: {$offset}"); + } + + return $this->codes[$offset]; + } + + /** + * @inheritDoc + */ + public function offsetExists($offset): bool + { + // Allow negative index + if ($offset < 0) { + $offset += $this->length; + } + + return isset($this->codes[$offset]); + } + + /** + * @inheritDoc + */ + public function offsetGet($offset): string + { + if ($offset < 0) { + if ($offset + $this->length < 0) { + throw new OutOfBoundsException("Undefined offset: {$offset}"); + } + $offset += $this->length; + } elseif ($offset >= $this->length) { + throw new OutOfBoundsException("Undefined offset: {$offset}"); + } + + return $this->chars()[$offset]; + } + + /** + * @inheritDoc + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + // Allow negative index + if ($offset < 0) { + $offset += $this->length; + } + + if (!isset($this->codes[$offset])) { + return; + } + + + $value = self::resolveFirstCodePoint($value); + if ($value === -1) { + return; + } + + if ($value === $this->codes[$offset]) { + // Same value, nothing to do + return; + } + + $this->codes[$offset] = $value; + + // Clear cache + $this->str = null; + $this->cache = null; + if ($this->chars) { + $this->chars[$offset] = self::getCharFromCodePoint($value); + } + } + + /** + * @inheritDoc + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + throw new RuntimeException("Invalid operation"); + } + + /** + * @inheritDoc + */ + public function count(): int + { + return $this->length; + } + + /** + * @return string + */ + public function __toString(): string + { + if ($this->str === null) { + $this->str = self::getStringFromCodePoints($this->codes); + } + + return $this->str; + } + + /** + * @inheritDoc + */ + public function jsonSerialize(): string + { + return $this->__toString(); + } + + public function __serialize(): array + { + return [ + 'value' => $this->__toString(), + ]; + } + + public function __unserialize(array $data): void + { + $this->str = $data['value']; + $this->codes = self::getCodePointsFromString($this->str); + $this->length = count($this->codes); + } + + /** + * Creates an unicode string instance from raw string + * @param string $string + * @param string|null $encoding Defaults to UTF-8 + * @param int $mode + * @return static + * @throws InvalidStringException + */ + public static function from(string $string, ?string $encoding = null, int $mode = self::KEEP_CASE): self + { + if ($encoding !== null && strcasecmp($encoding, 'UTF-8') !== 0) { + if (false === $string = @iconv($encoding, 'UTF-8', $string)) { + throw new UnicodeException("Could not convert string from '$encoding' encoding to UTF-8 encoding"); + } + } + + $instance = new static(self::getCodePointsFromString($string, $mode)); + if ($mode === self::KEEP_CASE) { + $instance->str = $string; + } + return $instance; + } + + /** + * Creates an unicode string instance from code points + * @param int[] $codes + * @param int $mode + * @return static + * @throws InvalidCodePointException + */ + public static function fromCodePoints(array $codes, int $mode = self::KEEP_CASE): self + { + $map = self::getMapByMode($mode); + + foreach ($codes as &$code) { + if (!is_int($codes) || !self::isValidCodePoint($code)) { + throw new InvalidCodePointException($code); + } else { + $code = $map[$code] ?? $code; + } + } + + return new static(array_values($codes)); + } + + /** + * Converts the code point to corresponding char + * @param int $code + * @return string The char or an empty string if code point is invalid + */ + public static function getCharFromCodePoint(int $code): string + { + if ($code < 0) { + return ''; + } + + if ($code < 0x80) { + return chr($code); + } + + if ($code < 0x800) { + return chr(($code >> 6) + 0xC0) . chr(($code & 0x3F) + 0x80); + } + + if ($code >= 0xD800 && $code <= 0xDFFF) { + /* + The definition of UTF-8 prohibits encoding character numbers between + U+D800 and U+DFFF, which are reserved for use with the UTF-16 + encoding form (as surrogate pairs) and do not directly represent characters. + */ + return ''; + } + + if ($code <= 0xFFFF) { + return + chr(($code >> 12) + 0xE0) . + chr((($code >> 6) & 0x3F) + 0x80) . + chr(($code & 0x3F) + 0x80); + } + + if ($code <= 0x10FFFF) { + return + chr(($code >> 18) + 0xF0) . + chr((($code >> 12) & 0x3F) + 0x80) . + chr((($code >> 6) & 0x3F) + 0x80) . + chr(($code & 0x3F) + 0x80); + } + + /* + Restricted the range of characters to 0000-10FFFF (the UTF-16 accessible range). + */ + + return ''; + } + + /** + * Convert a string to a code point array + * @param string $str + * @param int $mode + * @return array + * @throws InvalidStringException + */ + public static function getCodePointsFromString(string $str, int $mode = self::KEEP_CASE): array + { + // 0x00-0x7F + // 0xC2-0xDF 0x80-0xBF + // 0xE0-0xE0 0xA0-0xBF 0x80-0xBF + // 0xE1-0xEC 0x80-0xBF 0x80-0xBF + // 0xED-0xED 0x80-0x9F 0x80-0xBF + // 0xEE-0xEF 0x80-0xBF 0x80-0xBF + // 0xF0-0xF0 0x90-0xBF 0x80-0xBF 0x80-0xBF + // 0xF1-0xF3 0x80-0xBF 0x80-0xBF 0x80-0xBF + // 0xF4-0xF4 0x80-0x8F 0x80-0xBF 0x80-0xBF + + $codes = []; + $length = strlen($str); + $mode = self::getMapByMode($mode); + + $i = 0; + while ($i < $length) { + $ord0 = ord($str[$i++]); + + if ($ord0 < 0x80) { + $codes[] = $mode[$ord0] ?? $ord0; + continue; + } + + if ($i === $length || $ord0 < 0xC2 || $ord0 > 0xF4) { + throw new InvalidStringException($str, $i - 1); + } + + $ord1 = ord($str[$i++]); + + if ($ord0 < 0xE0) { + if ($ord1 < 0x80 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 1); + } + + $ord1 = ($ord0 - 0xC0) * 64 + $ord1 - 0x80; + $codes[] = $mode[$ord1] ?? $ord1; + + continue; + } + + if ($i === $length) { + throw new InvalidStringException($str, $i - 1); + } + + $ord2 = ord($str[$i++]); + + if ($ord0 < 0xF0) { + if ($ord0 === 0xE0) { + if ($ord1 < 0xA0 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 2); + } + } elseif ($ord0 === 0xED) { + if ($ord1 < 0x80 || $ord1 >= 0xA0) { + throw new InvalidStringException($str, $i - 2); + } + } elseif ($ord1 < 0x80 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 2); + } + + if ($ord2 < 0x80 || $ord2 >= 0xC0) { + throw new InvalidStringException($str, $i - 1); + } + + $ord2 = ($ord0 - 0xE0) * 0x1000 + ($ord1 - 0x80) * 64 + $ord2 - 0x80; + $codes[] = $mode[$ord2] ?? $ord2; + + continue; + } + + if ($i === $length) { + throw new InvalidStringException($str, $i - 1); + } + + $ord3 = ord($str[$i++]); + + if ($ord0 < 0xF5) { + if ($ord0 === 0xF0) { + if ($ord1 < 0x90 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 3); + } + } elseif ($ord0 === 0xF4) { + if ($ord1 < 0x80 || $ord1 >= 0x90) { + throw new InvalidStringException($str, $i - 3); + } + } elseif ($ord1 < 0x80 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 3); + } + + if ($ord2 < 0x80 || $ord2 >= 0xC0) { + throw new InvalidStringException($str, $i - 2); + } + + if ($ord3 < 0x80 || $ord3 >= 0xC0) { + throw new InvalidStringException($str, $i - 1); + } + + $ord3 = ($ord0 - 0xF0) * 0x40000 + ($ord1 - 0x80) * 0x1000 + ($ord2 - 0x80) * 64 + $ord3 - 0x80; + $codes[] = $mode[$ord3] ?? $ord3; + + continue; + } + + throw new InvalidStringException($str, $i - 1); + } + + return $codes; + } + + /** + * @param string $str + * @return iterable + * + * The key represents the current char index + * Value is a two element array + * - first element is an integer representing the code point + * - second element is an array of integers (length 1 to 4) representing bytes + */ + public static function walkString(string $str): iterable + { + $i = 0; + $length = strlen($str); + + while ($i < $length) { + $index = $i; + + $ord0 = ord($str[$i++]); + + if ($ord0 < 0x80) { + yield $index => [ + $ord0, + [$ord0] + ]; + continue; + } + + if ($i === $length || $ord0 < 0xC2 || $ord0 > 0xF4) { + throw new InvalidStringException($str, $i - 1); + } + + $ord1 = ord($str[$i++]); + + if ($ord0 < 0xE0) { + if ($ord1 < 0x80 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 1); + } + + yield $index => [ + ($ord0 - 0xC0) * 64 + $ord1 - 0x80, + [$ord0, $ord1] + ]; + + continue; + } + + if ($i === $length) { + throw new InvalidStringException($str, $i - 1); + } + + $ord2 = ord($str[$i++]); + + if ($ord0 < 0xF0) { + if ($ord0 === 0xE0) { + if ($ord1 < 0xA0 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 2); + } + } elseif ($ord0 === 0xED) { + if ($ord1 < 0x80 || $ord1 >= 0xA0) { + throw new InvalidStringException($str, $i - 2); + } + } elseif ($ord1 < 0x80 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 2); + } + + if ($ord2 < 0x80 || $ord2 >= 0xC0) { + throw new InvalidStringException($str, $i - 1); + } + + yield $index => [ + ($ord0 - 0xE0) * 0x1000 + ($ord1 - 0x80) * 64 + $ord2 - 0x80, + [$ord0, $ord1, $ord2] + ]; + + continue; + } + + if ($i === $length) { + throw new InvalidStringException($str, $i - 1); + } + + $ord3 = ord($str[$i++]); + + if ($ord0 < 0xF5) { + if ($ord0 === 0xF0) { + if ($ord1 < 0x90 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 3); + } + } elseif ($ord0 === 0xF4) { + if ($ord1 < 0x80 || $ord1 >= 0x90) { + throw new InvalidStringException($str, $i - 3); + } + } elseif ($ord1 < 0x80 || $ord1 >= 0xC0) { + throw new InvalidStringException($str, $i - 3); + } + + if ($ord2 < 0x80 || $ord2 >= 0xC0) { + throw new InvalidStringException($str, $i - 2); + } + + if ($ord3 < 0x80 || $ord3 >= 0xC0) { + throw new InvalidStringException($str, $i - 1); + } + + yield $index => [ + ($ord0 - 0xF0) * 0x40000 + ($ord1 - 0x80) * 0x1000 + ($ord2 - 0x80) * 64 + $ord3 - 0x80, + [$ord0, $ord1, $ord2, $ord3] + ]; + + continue; + } + + throw new InvalidStringException($str, $i - 1); + } + } + + /** + * Converts each code point to a char + * @param array $codes + * @param int $mode + * @return array + * @throws InvalidCodePointException + */ + public static function getCharsFromCodePoints(array $codes, int $mode = self::KEEP_CASE): array + { + $mode = self::getMapByMode($mode); + + foreach ($codes as &$code) { + $char = self::getCharFromCodePoint($mode[$code] ?? $code); + if ($char === '') { + throw new InvalidCodePointException($code); + } else { + $code = $char; + } + } + + return $codes; + } + + /** + * @param string $str + * @param int $mode + * @return string[] + */ + public static function getCharsFromString(string $str, int $mode = self::KEEP_CASE): array + { + return self::getCharsFromCodePoints(self::getCodePointsFromString($str), $mode); + } + + /** + * Converts all code points to chars and returns the string + * Invalid code points are ignored + * @param array $codes + * @param int $mode + * @return string + */ + public static function getStringFromCodePoints(array $codes, int $mode = self::KEEP_CASE): string + { + $str = ''; + + $mode = self::getMapByMode($mode); + + foreach ($codes as $code) { + if (isset($mode[$code])) { + $code = $mode[$code]; + } + + if ($code < 0x80) { + $str .= chr($code); + continue; + } + + if ($code < 0x800) { + $str .= chr(($code >> 6) + 0xC0) . chr(($code & 0x3F) + 0x80); + continue; + } + + if ($code >= 0xD800 && $code <= 0xDFFF) { + continue; + } + + if ($code <= 0xFFFF) { + $str .= + chr(($code >> 12) + 0xE0) . + chr((($code >> 6) & 0x3F) + 0x80) . + chr(($code & 0x3F) + 0x80); + continue; + } + + if ($code <= 0x10FFFF) { + $str .= + chr(($code >> 18) + 0xF0) . + chr((($code >> 12) & 0x3F) + 0x80) . + chr((($code >> 6) & 0x3F) + 0x80) . + chr(($code & 0x3F) + 0x80); + } + } + + return $str; + } + + /** + * @param array $codes + * @param int $mode + * @return array + */ + public static function getMappedCodePoints(array $codes, int $mode): array + { + if ($mode === self::KEEP_CASE) { + return $codes; + } + + $mode = self::getMapByMode($mode); + + if (empty($mode)) { + return $codes; + } + + foreach ($codes as &$code) { + $code = $mode[$code] ?? $code; + } + + return $codes; + } + + /** + * Checks if a code point is valid + * @param int $code + * @return bool + */ + public static function isValidCodePoint(int $code): bool + { + if ($code < 0 || $code > 0x10FFFF) { + return false; + } + + return $code < 0xD800 || $code > 0xDFFF; + } + + /** + * @param int $mode + * @return int[] + */ + private function getMappedCodes(int $mode): array + { + if ($mode === self::KEEP_CASE || ($this->cache['i' . $mode] ?? false)) { + return $this->codes; + } + + $key = 'm' . $mode; + + if (!isset($this->cache[$key])) { + $this->cache[$key] = self::getMappedCodePoints($this->codes, $mode); + } + + return $this->cache[$key]; + } + + /** + * @param int $mode + * @return bool + */ + private function isCase(int $mode): bool + { + $key = 'i' . $mode; + + if (!isset($this->cache[$key])) { + $list = self::getMapByMode($mode); + foreach ($this->codes as $code) { + if (isset($list[$code])) { + return $this->cache[$key] = false; + } + } + + return $this->cache[$key] = true; + } + + return $this->cache[$key]; + } + + /** + * @param int[] $codes + * @param int[] $text + * @param int $offset + * @return int + */ + private function doIndexOf(array $codes, array $text, int $offset = 0): int + { + $len = count($text); + + for ($i = $offset, $last = count($codes) - $len; $i <= $last; $i++) { + $match = true; + + for ($j = 0; $j < $len; $j++) { + if ($codes[$i + $j] !== $text[$j]) { + $match = false; + break; + } + } + + if ($match) { + return $i; + } + } + + return -1; + } + + /** + * @param string|self|int[]|string[] $mask + * @param bool $left + * @param bool $right + * @return static + */ + private function doTrim($mask, bool $left, bool $right): self + { + if ($this->length === 0) { + return clone $this; + } + + $mask = self::resolveCodePoints($mask); + + if (empty($mask)) { + return clone $this; + } + + $codes = $this->codes; + + if ($left) { + while (in_array($codes[0], $mask, true)) { + array_shift($codes); + if (empty($codes)) { + return new static(); + } + } + } + + if ($right) { + $last = count($codes) - 1; + while (in_array($codes[$last], $mask, true)) { + array_pop($codes); + if (--$last < 0) { + return new static(); + } + } + } + + return new static($codes); + } + + + /** + * @param string|self|int[]|string[] $text + * @param int $mode + * @return array + */ + private static function resolveCodePoints($text, int $mode = self::KEEP_CASE): array + { + if ($text instanceof self) { + return $text->getMappedCodes($mode); + } + + if (is_string($text)) { + return self::getCodePointsFromString($text, $mode); + } + + if ($text && is_array($text) && is_int($text[0])) { + // assume code point array + return self::getMappedCodePoints($text, $mode); + } + + return []; + } + + /** + * @param self|string|int|string[]|int[] $text + * @param int $invalid + * @return int + */ + private static function resolveFirstCodePoint($text, int $invalid = -1): int + { + if ($text instanceof self) { + return $text->length === 0 ? $invalid : $text->codes[0]; + } + + if (is_array($text)) { + if (empty($text)) { + return $invalid; + } + $text = reset($text); + } + + if (is_string($text)) { + if (isset($text[4])) { + $text = substr($text, 0, 4); + } + return self::getCodePointsFromString($text)[0] ?? $invalid; + } + + if (is_int($text)) { + return self::isValidCodePoint($text) ? $text : $invalid; + } + + return $invalid; + } + + /** + * @param int $mode + * @return int[] + */ + private static function getMapByMode(int $mode): array + { + if (isset(self::$maps[$mode])) { + return self::$maps[$mode]; + } + + switch ($mode) { + case self::LOWER_CASE: + $file = 'lower'; + break; + case self::UPPER_CASE: + $file = 'upper'; + break; + case self::ASCII_CONV: + $file = 'ascii'; + break; + case self::FOLD_CASE: + $file = 'fold'; + break; + default: + return []; + } + + /** @noinspection PhpIncludeInspection */ + return self::$maps[$mode] = include(__DIR__ . "/../res/{$file}.php"); + } +} diff --git a/vendor/opis/uri/autoload.php b/vendor/opis/uri/autoload.php new file mode 100644 index 0000000..8aa754c --- /dev/null +++ b/vendor/opis/uri/autoload.php @@ -0,0 +1,42 @@ += $n && $input[$i] < $m) { + $m = $input[$i]; + } + } + + if (($m - $n) > intdiv(self::MAX_INT - $delta, $handled + 1)) { + throw new PunycodeException("Punycode overflow"); + } + + $delta += ($m - $n) * ($handled + 1); + + $n = $m; + + for ($i = 0; $i < $input_len; $i++) { + if ($input[$i] < $n && (++$delta === 0)) { + throw new PunycodeException("Punycode overflow"); + } + + if ($input[$i] === $n) { + $q = $delta; + for ($k = self::BASE; ; $k += self::BASE) { + $t = self::threshold($k, $bias); + if ($q < $t) { + break; + } + + $base_minus_t = self::BASE - $t; + + $q -= $t; + + $output[] = self::encodeDigit($t + ($q % $base_minus_t)); + + $q = intdiv($q, $base_minus_t); + } + + $output[] = self::encodeDigit($q); + + $bias = self::adapt($delta, $handled + 1, $handled === $basic_length); + $delta = 0; + $handled++; + } + } + + $delta++; $n++; + } + + return self::PREFIX . UnicodeString::getStringFromCodePoints($output); + } + + public static function decodePart(string $input): string + { + if (stripos($input, self::PREFIX) !== 0) { + return $input; + } + + $input = UnicodeString::getCodePointsFromString(substr($input, self::PREFIX_LEN), UnicodeString::LOWER_CASE); + $input_len = count($input); + + $pos = array_keys($input, self::DELIMITER, true); + if ($pos) { + $pos = end($pos); + } else { + $pos = -1; + } + + /** @var int $pos */ + + if ($pos === -1) { + $output = []; + $pos = $output_len = 0; + } else { + $output = array_slice($input, 0, ++$pos); + $output_len = $pos; + for ($i = 0; $i < $pos; $i++) { + if ($output[$i] >= 0x80) { + throw new PunycodeException("Non-basic code point is not allowed: {$output[$i]}"); + } + } + } + + $i = 0; + $n = self::INITIAL_N; + $bias = self::INITIAL_BIAS; + + while ($pos < $input_len) { + $old_i = $i; + + for ($w = 1, $k = self::BASE; ; $k += self::BASE) { + if ($pos >= $input_len) { + throw new PunycodeException("Punycode bad input"); + } + + $digit = self::decodeDigit($input[$pos++]); + + if ($digit >= self::BASE || $digit > intdiv(self::MAX_INT - $i, $w)) { + throw new PunycodeException("Punycode overflow"); + } + + $i += $digit * $w; + + $t = self::threshold($k, $bias); + if ($digit < $t) { + break; + } + + $t = self::BASE - $t; + + if ($w > intdiv(self::MAX_INT, $t)) { + throw new PunycodeException("Punycode overflow"); + } + + $w *= $t; + } + + $output_len++; + + if (intdiv($i, $output_len) > self::MAX_INT - $n) { + throw new PunycodeException("Punycode overflow"); + } + + $n += intdiv($i, $output_len); + + $bias = self::adapt($i - $old_i, $output_len, $old_i === 0); + + $i %= $output_len; + + array_splice($output, $i, 0, $n); + + $i++; + } + + return UnicodeString::getStringFromCodePoints($output); + } + + public static function normalizePart(string $input): string + { + $input = strtolower($input); + + if (strpos($input, self::DELIMITER) === 0) { + self::decodePart($input); // just validate + return $input; + } + + return self::encodePart($input); + } + + private static function encodeDigit(int $digit): int + { + return $digit + 0x16 + ($digit < 0x1A ? 0x4B: 0x00); + } + + private static function decodeDigit(int $code): int + { + if ($code < 0x3A) { + return $code - 0x16; + } + if ($code < 0x5B) { + return $code - 0x41; + } + if ($code < 0x7B) { + return $code - 0x61; + } + + return self::BASE; + } + + private static function threshold(int $k, int $bias): int + { + $d = $k - $bias; + + if ($d <= self::TMIN) { + return self::TMIN; + } + + if ($d >= self::TMAX) { + return self::TMAX; + } + + return $d; + } + + private static function adapt(int $delta, int $num_points, bool $first_time = false): int + { + $delta = intdiv($delta, $first_time ? self::DAMP : 2); + $delta += intdiv($delta, $num_points); + + $k = 0; + $base_tmin_diff = self::BASE - self::TMIN; + $lim = $base_tmin_diff * self::TMAX / 2; + + while ($delta > $lim) { + $delta = intdiv($delta, $base_tmin_diff); + $k += self::BASE; + } + + $k += intdiv(($base_tmin_diff + 1) * $delta, $delta + self::SKEW); + + return $k; + } +} \ No newline at end of file diff --git a/vendor/opis/uri/src/PunycodeException.php b/vendor/opis/uri/src/PunycodeException.php new file mode 100644 index 0000000..6eb1c12 --- /dev/null +++ b/vendor/opis/uri/src/PunycodeException.php @@ -0,0 +1,25 @@ +[^:]+)(?::(?.*))?$`'; + + protected const HOST_LABEL_REGEX = '`^(?:(?:%[a-f0-9]{2})+|[a-z0-9-]+)*$`i'; + + protected const AUTHORITY_REGEX = '`^(?:(?[^@]+)\@)?(?(\[[a-f0-9:]+\]|[^:]+))(?::(?\d+))?$`i'; + + protected const PATH_REGEX = '`^(?:(?:%[a-f0-9]{2})+|[a-z0-9-._~!$&\'()*+,;=:@/]+)*$`i'; + + protected const QUERY_OR_FRAGMENT_REGEX = '`^(?:(?:%[a-f0-9]{2})+|[a-z0-9-._~!$&\'"()\[\]*+,;=:@?/%]+)*$`i'; + + protected array $components; + + protected ?string $str = null; + + /** + * @param array $components An array of normalized components + */ + public function __construct(array $components) + { + $this->components = $components + [ + 'scheme' => null, + 'user' => null, + 'pass' => null, + 'host' => null, + 'port' => null, + 'path' => null, + 'query' => null, + 'fragment' => null, + ]; + } + + /** + * @return string|null + */ + public function scheme(): ?string + { + return $this->components['scheme']; + } + + /** + * @return string|null + */ + public function user(): ?string + { + return $this->components['user']; + } + + /** + * @return string|null + */ + public function pass(): ?string + { + return $this->components['pass']; + } + + /** + * @return string|null + */ + public function userInfo(): ?string + { + if ($this->components['user'] === null) { + return null; + } + + if ($this->components['pass'] === null) { + return $this->components['user']; + } + + return $this->components['user'] . ':' . $this->components['pass']; + } + + /** + * @return string|null + */ + public function host(): ?string + { + return $this->components['host']; + } + + /** + * @return int|null + */ + public function port(): ?int + { + return $this->components['port']; + } + + /** + * @return string|null + */ + public function authority(): ?string + { + if ($this->components['host'] === null) { + return null; + } + + $authority = $this->userInfo(); + if ($authority !== null) { + $authority .= '@'; + } + + $authority .= $this->components['host']; + + if ($this->components['port'] !== null) { + $authority .= ':' . $this->components['port']; + } + + return $authority; + } + + /** + * @return string|null + */ + public function path(): ?string + { + return $this->components['path']; + } + + /** + * @return string|null + */ + public function query(): ?string + { + return $this->components['query']; + } + + /** + * @return string|null + */ + public function fragment(): ?string + { + return $this->components['fragment']; + } + + /** + * @return array|null[] + */ + public function components(): array + { + return $this->components; + } + + /** + * @return bool + */ + public function isAbsolute(): bool + { + return $this->components['scheme'] !== null; + } + + /** + * Use this URI as base to resolve the reference + * @param static|string|array $ref + * @param bool $normalize + * @return $this|null + */ + public function resolveRef($ref, bool $normalize = false): ?self + { + $ref = self::resolveComponents($ref); + if ($ref === null) { + return $this; + } + + return new static(self::mergeComponents($ref, $this->components, $normalize)); + } + + /** + * Resolve this URI reference using a base URI + * @param static|string|array $base + * @param bool $normalize + * @return static + */ + public function resolve($base, bool $normalize = false): self + { + if ($this->isAbsolute()) { + return $this; + } + + $base = self::resolveComponents($base); + + if ($base === null) { + return $this; + } + + return new static(self::mergeComponents($this->components, $base, $normalize)); + } + + /** + * @return string + */ + public function __toString(): string + { + if ($this->str !== null) { + return $this->str; + } + + $str = ''; + + if ($this->components['scheme'] !== null) { + $str .= $this->components['scheme'] . ':'; + } + + if ($this->components['host'] !== null) { + $str .= '//' . $this->authority(); + } + + $str .= $this->components['path']; + + if ($this->components['query'] !== null) { + $str .= '?' . $this->components['query']; + } + + if ($this->components['fragment'] !== null) { + $str .= '#' . $this->components['fragment']; + } + + return $this->str = $str; + } + + /** + * @param string $uri + * @param bool $normalize + * @return static|null + */ + public static function create(string $uri, bool $normalize = false): ?self + { + $comp = self::parseComponents($uri); + if (!$comp) { + return null; + } + + if ($normalize) { + $comp = self::normalizeComponents($comp); + } + + return new static($comp); + } + + /** + * Checks if the scheme contains valid chars + * @param string $scheme + * @return bool + */ + public static function isValidScheme(string $scheme): bool + { + return (bool)preg_match(self::SCHEME_REGEX, $scheme); + } + + /** + * Checks if user contains valid chars + * @param string $user + * @return bool + */ + public static function isValidUser(string $user): bool + { + return (bool)preg_match(self::USER_OR_PASS_REGEX, $user); + } + + /** + * Checks if pass contains valid chars + * @param string $pass + * @return bool + */ + public static function isValidPass(string $pass): bool + { + return (bool)preg_match(self::USER_OR_PASS_REGEX, $pass); + } + + /** + * @param string $userInfo + * @return bool + */ + public static function isValidUserInfo(string $userInfo): bool + { + /** @var array|string $userInfo */ + + if (!preg_match(self::USERINFO_REGEX, $userInfo, $userInfo)) { + return false; + } + + if (!self::isValidUser($userInfo['user'])) { + return false; + } + + if (isset($userInfo['pass'])) { + return self::isValidPass($userInfo['pass']); + } + + return true; + } + + /** + * Checks if host is valid + * @param string $host + * @return bool + */ + public static function isValidHost(string $host): bool + { + // min and max length + if ($host === '' || isset($host[253])) { + return false; + } + + // check ipv6 + if ($host[0] === '[') { + if ($host[-1] !== ']') { + return false; + } + + return filter_var( + substr($host, 1, -1), + \FILTER_VALIDATE_IP, + \FILTER_FLAG_IPV6 + ) !== false; + } + + // check ipv4 + if (preg_match('`^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\$`', $host)) { + return \filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4) !== false; + } + + foreach (explode('.', $host) as $host) { + // empty or too long label + if ($host === '' || isset($host[63])) { + return false; + } + if ($host[0] === '-' || $host[-1] === '-') { + return false; + } + if (!preg_match(self::HOST_LABEL_REGEX, $host)) { + return false; + } + } + + return true; + } + + /** + * Checks if the port is valid + * @param int $port + * @return bool + */ + public static function isValidPort(int $port): bool + { + return $port >= 0 && $port <= 65535; + } + + /** + * Checks if authority contains valid chars + * @param string $authority + * @return bool + */ + public static function isValidAuthority(string $authority): bool + { + if ($authority === '') { + return true; + } + + /** @var array|string $authority */ + + if (!preg_match(self::AUTHORITY_REGEX, $authority, $authority)) { + return false; + } + + if (isset($authority['port']) && !self::isValidPort((int)$authority['port'])) { + return false; + } + + if (isset($authority['userinfo']) && !self::isValidUserInfo($authority['userinfo'])) { + return false; + } + + return self::isValidHost($authority['host']); + } + + /** + * Checks if the path contains valid chars + * @param string $path + * @return bool + */ + public static function isValidPath(string $path): bool + { + return $path === '' || (bool)preg_match(self::PATH_REGEX, $path); + } + + /** + * Checks if the query string contains valid chars + * @param string $query + * @return bool + */ + public static function isValidQuery(string $query): bool + { + return $query === '' || (bool)preg_match(self::QUERY_OR_FRAGMENT_REGEX, $query); + } + + /** + * Checks if the fragment contains valid chars + * @param string $fragment + * @return bool + */ + public static function isValidFragment(string $fragment): bool + { + return $fragment === '' || (bool)preg_match(self::QUERY_OR_FRAGMENT_REGEX, $fragment); + } + + /** + * @param string $uri + * @param bool $expand_authority + * @param bool $validate + * @return array|null + */ + public static function parseComponents(string $uri, bool $expand_authority = true, bool $validate = true): ?array + { + if (!preg_match(self::URI_REGEX, $uri, $uri)) { + return null; + } + + $comp = []; + + // scheme + if (isset($uri[2]) && $uri[2] !== '') { + if ($validate && !self::isValidScheme($uri[2])) { + return null; + } + $comp['scheme'] = $uri[2]; + } + + // authority + if (isset($uri[4]) && isset($uri[3][0])) { + if ($uri[4] === '') { + if ($expand_authority) { + $comp['host'] = ''; + } else { + $comp['authority'] = ''; + } + } elseif ($expand_authority) { + $au = self::parseAuthorityComponents($uri[4], $validate); + if ($au === null) { + return null; + } + $comp += $au; + unset($au); + } else { + if ($validate && !self::isValidAuthority($uri[4])) { + return null; + } + $comp['authority'] = $uri[4]; + } + } + + // path + if (isset($uri[5])) { + if ($validate && !self::isValidPath($uri[5])) { + return null; + } + $comp['path'] = $uri[5]; + // not a relative uri, remove dot segments + if (isset($comp['scheme']) || isset($comp['authority']) || isset($comp['host'])) { + $comp['path'] = self::removeDotSegmentsFromPath($comp['path']); + } + } + + // query + if (isset($uri[7]) && isset($uri[6][0])) { + if ($validate && !self::isValidQuery($uri[7])) { + return null; + } + $comp['query'] = $uri[7]; + } + + // fragment + if (isset($uri[9]) && isset($uri[8][0])) { + if ($validate && !self::isValidFragment($uri[9])) { + return null; + } + $comp['fragment'] = $uri[9]; + } + + return $comp; + } + + /** + * @param self|string|array $uri + * @return array|null + */ + public static function resolveComponents($uri): ?array + { + if ($uri instanceof self) { + return $uri->components; + } + + if (is_string($uri)) { + return self::parseComponents($uri); + } + + if (is_array($uri)) { + if (isset($uri['host'])) { + unset($uri['authority']); + } elseif (isset($uri['authority'])) { + $au = self::parseAuthorityComponents($uri['authority']); + unset($uri['authority']); + if ($au !== null) { + unset($uri['user'], $uri['pass'], $uri['host'], $uri['port']); + $uri += $au; + } + } + return $uri; + } + + return null; + } + + /** + * @param string $authority + * @param bool $validate + * @return array|null + */ + public static function parseAuthorityComponents(string $authority, bool $validate = true): ?array + { + /** @var array|string $authority */ + + if (!preg_match(self::AUTHORITY_REGEX, $authority, $authority)) { + return null; + } + + $comp = []; + + // userinfo + if (isset($authority['userinfo']) && $authority['userinfo'] !== '') { + if (!preg_match(self::USERINFO_REGEX, $authority['userinfo'], $ui)) { + return null; + } + + // user + if ($validate && !self::isValidUser($ui['user'])) { + return null; + } + $comp['user'] = $ui['user']; + + // pass + if (isset($ui['pass']) && $ui['pass'] !== '') { + if ($validate && !self::isValidPass($ui['pass'])) { + return null; + } + $comp['pass'] = $ui['pass']; + } + + unset($ui); + } + + // host + if ($validate && !self::isValidHost($authority['host'])) { + return null; + } + $comp['host'] = $authority['host']; + + + // port + if (isset($authority['port'])) { + $authority['port'] = (int)$authority['port']; + if (!self::isValidPort($authority['port'])) { + return null; + } + $comp['port'] = $authority['port']; + } + + return $comp; + } + + /** + * @param array $ref + * @param array $base + * @param bool $normalize + * @return array + */ + public static function mergeComponents(array $ref, array $base, bool $normalize = false): array + { + if (isset($ref['scheme'])) { + $dest = $ref; + } else { + $dest = []; + + $dest['scheme'] = $base['scheme'] ?? null; + + if (isset($ref['authority']) || isset($ref['host'])) { + $dest += $ref; + } else { + if (isset($base['authority'])) { + $dest['authority'] = $base['authority']; + } else { + $dest['user'] = $base['user'] ?? null; + $dest['pass'] = $base['pass'] ?? null; + $dest['host'] = $base['host'] ?? null; + $dest['port'] = $base['port'] ?? null; + } + + if (!isset($ref['path'])) { + $ref['path'] = ''; + } + if (!isset($base['path'])) { + $base['path'] = ''; + } + + if ($ref['path'] === '') { + $dest['path'] = $base['path']; + $dest['query'] = $ref['query'] ?? $base['query'] ?? null; + } else { + if ($ref['path'][0] === '/') { + $dest['path'] = $ref['path']; + } else { + if ((isset($base['authority']) || isset($base['host'])) && $base['path'] === '') { + $dest['path'] = '/' . $ref['path']; + } else { + $dest['path'] = $base['path']; + + if ($dest['path'] !== '') { + $pos = strrpos($dest['path'], '/'); + if ($pos === false) { + $dest['path'] = ''; + } else { + $dest['path'] = substr($dest['path'], 0, $pos); + } + + unset($pos); + } + $dest['path'] .= '/' . $ref['path']; + } + } + + $dest['query'] = $ref['query'] ?? null; + } + } + } + + $dest['fragment'] = $ref['fragment'] ?? null; + + if ($normalize) { + return self::normalizeComponents($dest); + } + + if (isset($dest['path'])) { + $dest['path'] = self::removeDotSegmentsFromPath($dest['path']); + } + + return $dest; + } + + public static function normalizeComponents(array $components): array + { + if (isset($components['scheme'])) { + $components['scheme'] = strtolower($components['scheme']); + // Remove default port + if (isset($components['port']) && self::getSchemePort($components['scheme']) === $components['port']) { + $components['port'] = null; + } + } + + if (isset($components['host'])) { + $components['host'] = strtolower($components['host']); + } + + if (isset($components['path'])) { + $components['path'] = self::removeDotSegmentsFromPath($components['path']); + } + + if (isset($components['query'])) { + $components['query'] = self::normalizeQueryString($components['query']); + } + + return $components; + } + + /** + * Removes dot segments from path + * @param string $path + * @return string + */ + public static function removeDotSegmentsFromPath(string $path): string + { + // Fast check common simple paths + if ($path === '' || $path === '/') { + return $path; + } + + $output = ''; + $last_slash = 0; + + $len = strlen($path); + $i = 0; + + while ($i < $len) { + if ($path[$i] === '.') { + $j = $i + 1; + // search for . + if ($j >= $len) { + break; + } + + // search for ./ + if ($path[$j] === '/') { + $i = $j + 1; + continue; + } + + // search for ../ + if ($path[$j] === '.') { + $k = $j + 1; + if ($k >= $len) { + break; + } + if ($path[$k] === '/') { + $i = $k + 1; + continue; + } + } + } elseif ($path[$i] === '/') { + $j = $i + 1; + if ($j >= $len) { + $output .= '/'; + break; + } + + // search for /. + if ($path[$j] === '.') { + $k = $j + 1; + if ($k >= $len) { + $output .= '/'; + break; + } + // search for /./ + if ($path[$k] === '/') { + $i = $k; + continue; + } + // search for /.. + if ($path[$k] === '.') { + $n = $k + 1; + if ($n >= $len) { + // keep the slash + $output = substr($output, 0, $last_slash + 1); + break; + } + // search for /../ + if ($path[$n] === '/') { + $output = substr($output, 0, $last_slash); + $last_slash = (int)strrpos($output, '/'); + $i = $n; + continue; + } + } + } + } + + $pos = strpos($path, '/', $i + 1); + + if ($pos === false) { + $output .= substr($path, $i); + break; + } + + $last_slash = strlen($output); + $output .= substr($path, $i, $pos - $i); + + $i = $pos; + } + + return $output; + } + + /** + * @param string|null $query + * @return array + */ + public static function parseQueryString(?string $query): array + { + if ($query === null) { + return []; + } + + $list = []; + + foreach (explode('&', $query) as $name) { + $value = null; + if (($pos = strpos($name, '=')) !== false) { + $value = self::decodeComponent(substr($name, $pos + 1)); + $name = self::decodeComponent(substr($name, 0, $pos)); + } else { + $name = self::decodeComponent($name); + } + $list[$name] = $value; + } + + return $list; + } + + /** + * @param array $qs + * @param string|null $prefix + * @param string $separator + * @param bool $sort + * @return string + */ + public static function buildQueryString(array $qs, ?string $prefix = null, + string $separator = '&', bool $sort = false): string + { + $isIndexed = static function (array $array): bool { + for ($i = 0, $max = count($array); $i < $max; $i++) { + if (!array_key_exists($i, $array)) { + return false; + } + } + return true; + }; + + $f = static function (array $arr, ?string $prefix = null) use (&$f, &$isIndexed): iterable { + $indexed = $prefix !== null && $isIndexed($arr); + + foreach ($arr as $key => $value) { + if ($prefix !== null) { + $key = $prefix . ($indexed ? "[]" : "[{$key}]"); + } + if (is_array($value)) { + yield from $f($value, $key); + } else { + yield $key => $value; + } + } + }; + + $data = []; + + foreach ($f($qs, $prefix) as $key => $value) { + $item = is_string($key) ? self::encodeComponent($key) : $key; + if ($value !== null) { + $item .= '='; + $item .= is_string($value) ? self::encodeComponent($value) : $value; + } + if ($item === '' || $item === '=') { + continue; + } + $data[] = $item; + } + + if (!$data) { + return ''; + } + + if ($sort) { + sort($data); + } + + return implode($separator, $data); + } + + /** + * @param string $query + * @return string + */ + public static function normalizeQueryString(string $query): string + { + return static::buildQueryString(self::parseQueryString($query), null, '&', true); + } + + public static function decodeComponent(string $component): string + { + return rawurldecode($component); + } + + public static function encodeComponent(string $component, ?array $skip = null): string + { + if (!$skip) { + return rawurlencode($component); + } + + $str = ''; + + foreach (UnicodeString::walkString($component) as [$cp, $chars]) { + if ($cp < 0x80) { + if ($cp === 0x2D || $cp === 0x2E || + $cp === 0x5F || $cp === 0x7E || + ($cp >= 0x41 && $cp <= 0x5A) || + ($cp >= 0x61 && $cp <= 0x7A) || + ($cp >= 0x30 && $cp <= 0x39) || + in_array($cp, $skip, true) + ) { + $str .= chr($cp); + } else { + $str .= '%' . strtoupper(dechex($cp)); + } + } else { + $i = 0; + while (isset($chars[$i])) { + $str .= '%' . strtoupper(dechex($chars[$i++])); + } + } + } + + return $str; + } + + public static function setSchemePort(string $scheme, ?int $port): void + { + $scheme = strtolower($scheme); + + if ($port === null) { + unset(self::$KNOWN_PORTS[$scheme]); + } else { + self::$KNOWN_PORTS[$scheme] = $port; + } + } + + public static function getSchemePort(string $scheme): ?int + { + return self::$KNOWN_PORTS[strtolower($scheme)] ?? null; + } + + protected static array $KNOWN_PORTS = [ + 'ftp' => 21, + 'ssh' => 22, + 'telnet' => 23, + 'smtp' => 25, + 'tftp' => 69, + 'http' => 80, + 'pop' => 110, + 'sftp' => 115, + 'imap' => 143, + 'irc' => 194, + 'ldap' => 389, + 'https' => 443, + 'ldaps' => 636, + 'telnets' => 992, + 'imaps' => 993, + 'ircs' => 994, + 'pops' => 995, + ]; +} \ No newline at end of file diff --git a/vendor/opis/uri/src/UriTemplate.php b/vendor/opis/uri/src/UriTemplate.php new file mode 100644 index 0000000..98c5b69 --- /dev/null +++ b/vendor/opis/uri/src/UriTemplate.php @@ -0,0 +1,520 @@ +[a-zA-Z0-9\_\%\.]+)(?:(?\*)?|\:(?\d+))?$~'; + + /** @var string */ + protected const TEMPLATE_REGEX = <<<'REGEX' +~\{ +(?[+#./;&=,!@|\?])? +(? + (?:(?P>varspec),)* + (?(?: + [a-zA-Z0-9\_\%\.]+ + (?:\*|\:\d+)? + )) +) +\}~x +REGEX; + + /** @var array */ + protected const TEMPLATE_TABLE = [ + '' => [ + 'first' => '', + 'sep' => ',', + 'named' => false, + 'ifemp' => '', + 'allow' => false, + ], + '+' => [ + 'first' => '', + 'sep' => ',', + 'named' => false, + 'ifemp' => '', + 'allow' => true, + ], + '.' => [ + 'first' => '.', + 'sep' => '.', + 'named' => false, + 'ifemp' => '', + 'allow' => false, + ], + '/' => [ + 'first' => '/', + 'sep' => '/', + 'named' => false, + 'ifemp' => '', + 'allow' => false, + ], + ';' => [ + 'first' => ';', + 'sep' => ';', + 'named' => true, + 'ifemp' => '', + 'allow' => false, + ], + '?' => [ + 'first' => '?', + 'sep' => '&', + 'named' => true, + 'ifemp' => '=', + 'allow' => false, + ], + '&' => [ + 'first' => '&', + 'sep' => '&', + 'named' => true, + 'ifemp' => '=', + 'allow' => false, + ], + '#' => [ + 'first' => '#', + 'sep' => ',', + 'named' => false, + 'ifemp' => '', + 'allow' => true, + ], + ]; + + protected string $uri; + + /** @var bool|null|array */ + protected $parsed = false; + + /** + * UriTemplate constructor. + * @param string $uri_template + */ + public function __construct(string $uri_template) + { + $this->uri = $uri_template; + } + + /** + * @param array $vars + * @return string + */ + public function resolve(array $vars): string + { + if ($this->parsed === false) { + $this->parsed = $this->parse($this->uri); + } + if ($this->parsed === null || !$vars) { + return $this->uri; + } + + $data = ''; + $vars = $this->prepareVars($vars); + + foreach ($this->parsed as $item) { + if (!is_array($item)) { + $data .= $item; + continue; + } + + $data .= $this->parseTemplateExpression( + self::TEMPLATE_TABLE[$item['operator']], + $this->resolveVars($item['vars'], $vars) + ); + } + + return $data; + } + + /** + * @return bool + */ + public function hasPlaceholders(): bool + { + if ($this->parsed === false) { + $this->parse($this->uri); + } + + return $this->parsed !== null; + } + + /** + * @param string $uri + * @return array|null + */ + protected function parse(string $uri): ?array + { + $placeholders = null; + preg_match_all(self::TEMPLATE_REGEX, $uri, $placeholders, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); + + if (!$placeholders) { + return null; + } + + $dataIndex = -1; + $data = []; + + $hasVars = false; + $nextOffset = 0; + foreach ($placeholders as &$p) { + $offset = $p[0][1]; + if ($nextOffset < $offset) { + $data[] = substr($uri, $nextOffset, $offset - $nextOffset); + $dataIndex++; + } + $matched = $p[0][0]; + $nextOffset = $offset + strlen($matched); + + $operator = $p['operator'][0] ?? null; + if ($operator === null || !isset(self::TEMPLATE_TABLE[$operator])) { + if ($dataIndex >= 0 && is_string($data[$dataIndex])) { + $data[$dataIndex] .= $matched; + } else { + $data[] = $matched; + $dataIndex++; + } + continue; + } + + $varList = $p['varlist'][0] ?? ''; + $varList = $varList === '' ? [] : explode(',', $varList); + $p = null; + + $varData = []; + + foreach ($varList as $var) { + if (!preg_match(self::TEMPLATE_VARSPEC_REGEX, $var, $spec)) { + continue; + } + + $varData[] = [ + 'name' => $spec['varname'], + 'explode' => isset($spec['explode']) && $spec['explode'] === '*', + 'prefix' => isset($spec['prefix']) ? (int)$spec['prefix'] : 0, + ]; + + unset($var, $spec); + } + + if ($varData) { + $hasVars = true; + $data[] = [ + 'operator' => $operator, + 'vars' => $varData, + ]; + $dataIndex++; + } else { + if ($dataIndex >= 0 && is_string($data[$dataIndex])) { + $data[$dataIndex] .= $matched; + } else { + $data[] = $matched; + $dataIndex++; + } + } + + unset($varData, $varList, $operator); + } + + if (!$hasVars) { + return null; + } + + $matched = substr($uri, $nextOffset); + if ($matched !== false && $matched !== '') { + if ($dataIndex >= 0 && is_string($data[$dataIndex])) { + $data[$dataIndex] .= $matched; + } else { + $data[] = $matched; + } + } + + return $data; + } + + /** + * Convert assoc arrays to objects + * @param array $vars + * @return array + */ + protected function prepareVars(array $vars): array + { + foreach ($vars as &$value) { + if (is_scalar($value)) { + if (!is_string($value)) { + $value = (string)$value; + } + continue; + } + + if (!is_array($value)) { + continue; + } + + $len = count($value); + for ($i = 0; $i < $len; $i++) { + if (!array_key_exists($i, $value)) { + $value = (object)$value; + break; + } + } + } + + return $vars; + } + + /** + * @param array $vars + * @param array $data + * @return array + */ + protected function resolveVars(array $vars, array $data): array + { + $resolved = []; + + foreach ($vars as $info) { + $name = $info['name']; + + if (!isset($data[$name])) { + continue; + } + + $resolved[] = $info + ['value' => &$data[$name]]; + } + + return $resolved; + } + + /** + * @param array $table + * @param array $data + * @return string + */ + protected function parseTemplateExpression(array $table, array $data): string + { + $result = []; + foreach ($data as $var) { + $str = ""; + if (is_string($var['value'])) { + if ($table['named']) { + $str .= $var['name']; + if ($var['value'] === '') { + $str .= $table['ifemp']; + } else { + $str .= '='; + } + } + if ($var['prefix']) { + $str .= $this->encodeTemplateString(self::prefix($var['value'], $var['prefix']), $table['allow']); + } else { + $str .= $this->encodeTemplateString($var['value'], $table['allow']); + } + } elseif ($var['explode']) { + $list = []; + if ($table['named']) { + if (is_array($var['value'])) { + foreach ($var['value'] as $v) { + if (is_null($v) || !is_scalar($v)) { + continue; + } + $v = $this->encodeTemplateString((string)$v, $table['allow']); + if ($v === '') { + $list[] = $var['name'] . $table['ifemp']; + } else { + $list[] = $var['name'] . '=' . $v; + } + } + } elseif (is_object($var['value'])) { + foreach ($var['value'] as $prop => $v) { + if (is_null($v) || !is_scalar($v)) { + continue; + } + $v = $this->encodeTemplateString((string)$v, $table['allow']); + $prop = $this->encodeTemplateString((string)$prop, $table['allow']); + if ($v === '') { + $list[] = $prop . $table['ifemp']; + } else { + $list[] = $prop . '=' . $v; + } + } + } + } else { + if (is_array($var['value'])) { + foreach ($var['value'] as $v) { + if (is_null($v) || !is_scalar($v)) { + continue; + } + $list[] = $this->encodeTemplateString($v, $table['allow']); + } + } elseif (is_object($var['value'])) { + foreach ($var['value'] as $prop => $v) { + if (is_null($v) || !is_scalar($v)) { + continue; + } + $v = $this->encodeTemplateString((string)$v, $table['allow']); + $prop = $this->encodeTemplateString((string)$prop, $table['allow']); + $list[] = $prop . '=' . $v; + } + } + } + + if ($list) { + $str .= implode($table['sep'], $list); + } + unset($list); + } else { + if ($table['named']) { + $str .= $var['name']; + if ($var['value'] === '') { + $str .= $table['ifemp']; + } else { + $str .= '='; + } + } + $list = []; + if (is_array($var['value'])) { + foreach ($var['value'] as $v) { + $list[] = $this->encodeTemplateString($v, $table['allow']); + } + } elseif (is_object($var['value'])) { + foreach ($var['value'] as $prop => $v) { + $list[] = $this->encodeTemplateString((string)$prop, $table['allow']); + $list[] = $this->encodeTemplateString((string)$v, $table['allow']); + } + } + if ($list) { + $str .= implode(',', $list); + } + unset($list); + } + + if ($str !== '') { + $result[] = $str; + } + } + + if (!$result) { + return ''; + } + + $result = implode($table['sep'], $result); + + if ($result !== '') { + $result = $table['first'] . $result; + } + + return $result; + } + + /** + * @param string $data + * @param bool $reserved + * @return string + */ + protected function encodeTemplateString(string $data, bool $reserved): string + { + $skip = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'; + + if ($reserved) { + $skip .= ':/?#[]@!$&\'()*+,;='; + } + + $result = ''; + $temp = ''; + for ($i = 0, $len = strlen($data); $i < $len; $i++) { + if (strpos($skip, $data[$i]) !== false) { + if ($temp !== '') { + $result .= Uri::encodeComponent($temp); + $temp = ''; + } + $result .= $data[$i]; + continue; + } + if ($reserved && $data[$i] === '%') { + if (isset($data[$i + 1]) && isset($data[$i + 2]) + && strpos('ABCDEF0123456789', $data[$i + 1]) !== false + && strpos('ABCDEF0123456789', $data[$i + 2]) !== false) { + if ($temp !== '') { + $result .= Uri::encodeComponent($temp); + } + $result .= '%' . $data[$i + 1] . $data[$i + 2]; + $i += 3; + continue; + } + } + $temp .= $data[$i]; + } + + if ($temp !== '') { + $result .= Uri::encodeComponent($temp); + } + + return $result; + } + + /** + * @return string + */ + public function value(): string + { + return $this->uri; + } + + public function __toString(): string + { + return $this->uri; + } + + /** + * @param string $uri + * @return bool + */ + public static function isTemplate(string $uri): bool + { + $open = substr_count($uri, '{'); + if ($open === 0) { + return false; + } + $close = substr_count($uri, '}'); + if ($open !== $close) { + return false; + } + + return (bool)preg_match(self::TEMPLATE_REGEX, $uri); + } + + /** + * @param string $str + * @param int $len + * @return string + */ + protected static function prefix(string $str, int $len): string + { + if ($len === 0) { + return ''; + } + + if ($len >= strlen($str)) { + // Prefix is longer than string length + return $str; + } + + return (string)UnicodeString::from($str)->substring(0, $len); + } +} \ No newline at end of file diff --git a/vendor/paragonie/constant_time_encoding/src/Base32.php b/vendor/paragonie/constant_time_encoding/src/Base32.php index 7508b3d..48d00b9 100644 --- a/vendor/paragonie/constant_time_encoding/src/Base32.php +++ b/vendor/paragonie/constant_time_encoding/src/Base32.php @@ -44,8 +44,11 @@ abstract class Base32 implements EncoderInterface * @param bool $strictPadding * @return string */ - public static function decode(string $encodedString, bool $strictPadding = false): string - { + public static function decode( + #[\SensitiveParameter] + string $encodedString, + bool $strictPadding = false + ): string { return static::doDecode($encodedString, false, $strictPadding); } @@ -56,8 +59,11 @@ public static function decode(string $encodedString, bool $strictPadding = false * @param bool $strictPadding * @return string */ - public static function decodeUpper(string $src, bool $strictPadding = false): string - { + public static function decodeUpper( + #[\SensitiveParameter] + string $src, + bool $strictPadding = false + ): string { return static::doDecode($src, true, $strictPadding); } @@ -68,10 +74,13 @@ public static function decodeUpper(string $src, bool $strictPadding = false): st * @return string * @throws TypeError */ - public static function encode(string $binString): string - { + public static function encode( + #[\SensitiveParameter] + string $binString + ): string { return static::doEncode($binString, false, true); } + /** * Encode into Base32 (RFC 4648) * @@ -79,8 +88,10 @@ public static function encode(string $binString): string * @return string * @throws TypeError */ - public static function encodeUnpadded(string $src): string - { + public static function encodeUnpadded( + #[\SensitiveParameter] + string $src + ): string { return static::doEncode($src, false, false); } @@ -91,8 +102,10 @@ public static function encodeUnpadded(string $src): string * @return string * @throws TypeError */ - public static function encodeUpper(string $src): string - { + public static function encodeUpper( + #[\SensitiveParameter] + string $src + ): string { return static::doEncode($src, true, true); } @@ -103,8 +116,10 @@ public static function encodeUpper(string $src): string * @return string * @throws TypeError */ - public static function encodeUpperUnpadded(string $src): string - { + public static function encodeUpperUnpadded( + #[\SensitiveParameter] + string $src + ): string { return static::doEncode($src, true, false); } @@ -191,8 +206,11 @@ protected static function encode5BitsUpper(int $src): string * @param bool $upper * @return string */ - public static function decodeNoPadding(string $encodedString, bool $upper = false): string - { + public static function decodeNoPadding( + #[\SensitiveParameter] + string $encodedString, + bool $upper = false + ): string { $srcLen = Binary::safeStrlen($encodedString); if ($srcLen === 0) { return ''; @@ -222,9 +240,9 @@ public static function decodeNoPadding(string $encodedString, bool $upper = fals * @return string * * @throws TypeError - * @psalm-suppress RedundantCondition */ protected static function doDecode( + #[\SensitiveParameter] string $src, bool $upper = false, bool $strictPadding = false @@ -434,8 +452,12 @@ protected static function doDecode( * @return string * @throws TypeError */ - protected static function doEncode(string $src, bool $upper = false, $pad = true): string - { + protected static function doEncode( + #[\SensitiveParameter] + string $src, + bool $upper = false, + $pad = true + ): string { // We do this to reduce code duplication: $method = $upper ? 'encode5BitsUpper' diff --git a/vendor/paragonie/constant_time_encoding/src/Base64.php b/vendor/paragonie/constant_time_encoding/src/Base64.php index f571617..2e3ecc8 100644 --- a/vendor/paragonie/constant_time_encoding/src/Base64.php +++ b/vendor/paragonie/constant_time_encoding/src/Base64.php @@ -47,8 +47,10 @@ abstract class Base64 implements EncoderInterface * * @throws TypeError */ - public static function encode(string $binString): string - { + public static function encode( + #[\SensitiveParameter] + string $binString + ): string { return static::doEncode($binString, true); } @@ -62,8 +64,10 @@ public static function encode(string $binString): string * * @throws TypeError */ - public static function encodeUnpadded(string $src): string - { + public static function encodeUnpadded( + #[\SensitiveParameter] + string $src + ): string { return static::doEncode($src, false); } @@ -74,8 +78,11 @@ public static function encodeUnpadded(string $src): string * * @throws TypeError */ - protected static function doEncode(string $src, bool $pad = true): string - { + protected static function doEncode( + #[\SensitiveParameter] + string $src, + bool $pad = true + ): string { $dest = ''; $srcLen = Binary::safeStrlen($src); // Main loop (no padding): @@ -129,10 +136,12 @@ protected static function doEncode(string $src, bool $pad = true): string * * @throws RangeException * @throws TypeError - * @psalm-suppress RedundantCondition */ - public static function decode(string $encodedString, bool $strictPadding = false): string - { + public static function decode( + #[\SensitiveParameter] + string $encodedString, + bool $strictPadding = false + ): string { // Remove padding $srcLen = Binary::safeStrlen($encodedString); if ($srcLen === 0) { @@ -227,25 +236,21 @@ public static function decode(string $encodedString, bool $strictPadding = false * @param string $encodedString * @return string */ - public static function decodeNoPadding(string $encodedString): string - { + public static function decodeNoPadding( + #[\SensitiveParameter] + string $encodedString + ): string { $srcLen = Binary::safeStrlen($encodedString); if ($srcLen === 0) { return ''; } if (($srcLen & 3) === 0) { - if ($encodedString[$srcLen - 1] === '=') { + // If $strLen is not zero, and it is divisible by 4, then it's at least 4. + if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') { throw new InvalidArgumentException( "decodeNoPadding() doesn't tolerate padding" ); } - if (($srcLen & 3) > 1) { - if ($encodedString[$srcLen - 2] === '=') { - throw new InvalidArgumentException( - "decodeNoPadding() doesn't tolerate padding" - ); - } - } } return static::decode( $encodedString, diff --git a/vendor/paragonie/constant_time_encoding/src/Binary.php b/vendor/paragonie/constant_time_encoding/src/Binary.php index 828f3e0..5368e4b 100644 --- a/vendor/paragonie/constant_time_encoding/src/Binary.php +++ b/vendor/paragonie/constant_time_encoding/src/Binary.php @@ -45,8 +45,10 @@ abstract class Binary * @param string $str * @return int */ - public static function safeStrlen(string $str): int - { + public static function safeStrlen( + #[\SensitiveParameter] + string $str + ): int { if (\function_exists('mb_strlen')) { // mb_strlen in PHP 7.x can return false. /** @psalm-suppress RedundantCast */ @@ -70,6 +72,7 @@ public static function safeStrlen(string $str): int * @throws TypeError */ public static function safeSubstr( + #[\SensitiveParameter] string $str, int $start = 0, $length = null diff --git a/vendor/paragonie/constant_time_encoding/src/Encoding.php b/vendor/paragonie/constant_time_encoding/src/Encoding.php index 8649f31..8b7e387 100644 --- a/vendor/paragonie/constant_time_encoding/src/Encoding.php +++ b/vendor/paragonie/constant_time_encoding/src/Encoding.php @@ -40,8 +40,10 @@ abstract class Encoding * @return string * @throws TypeError */ - public static function base32Encode(string $str): string - { + public static function base32Encode( + #[\SensitiveParameter] + string $str + ): string { return Base32::encode($str); } @@ -52,8 +54,10 @@ public static function base32Encode(string $str): string * @return string * @throws TypeError */ - public static function base32EncodeUpper(string $str): string - { + public static function base32EncodeUpper( + #[\SensitiveParameter] + string $str + ): string { return Base32::encodeUpper($str); } @@ -64,8 +68,10 @@ public static function base32EncodeUpper(string $str): string * @return string * @throws TypeError */ - public static function base32Decode(string $str): string - { + public static function base32Decode( + #[\SensitiveParameter] + string $str + ): string { return Base32::decode($str); } @@ -76,8 +82,10 @@ public static function base32Decode(string $str): string * @return string * @throws TypeError */ - public static function base32DecodeUpper(string $str): string - { + public static function base32DecodeUpper( + #[\SensitiveParameter] + string $str + ): string { return Base32::decodeUpper($str); } @@ -88,8 +96,10 @@ public static function base32DecodeUpper(string $str): string * @return string * @throws TypeError */ - public static function base32HexEncode(string $str): string - { + public static function base32HexEncode( + #[\SensitiveParameter] + string $str + ): string { return Base32Hex::encode($str); } @@ -100,8 +110,10 @@ public static function base32HexEncode(string $str): string * @return string * @throws TypeError */ - public static function base32HexEncodeUpper(string $str): string - { + public static function base32HexEncodeUpper( + #[\SensitiveParameter] + string $str + ): string { return Base32Hex::encodeUpper($str); } @@ -112,8 +124,10 @@ public static function base32HexEncodeUpper(string $str): string * @return string * @throws TypeError */ - public static function base32HexDecode(string $str): string - { + public static function base32HexDecode( + #[\SensitiveParameter] + string $str + ): string { return Base32Hex::decode($str); } @@ -124,8 +138,10 @@ public static function base32HexDecode(string $str): string * @return string * @throws TypeError */ - public static function base32HexDecodeUpper(string $str): string - { + public static function base32HexDecodeUpper( + #[\SensitiveParameter] + string $str + ): string { return Base32Hex::decodeUpper($str); } @@ -136,8 +152,10 @@ public static function base32HexDecodeUpper(string $str): string * @return string * @throws TypeError */ - public static function base64Encode(string $str): string - { + public static function base64Encode( + #[\SensitiveParameter] + string $str + ): string { return Base64::encode($str); } @@ -148,8 +166,10 @@ public static function base64Encode(string $str): string * @return string * @throws TypeError */ - public static function base64Decode(string $str): string - { + public static function base64Decode( + #[\SensitiveParameter] + string $str + ): string { return Base64::decode($str); } @@ -161,8 +181,10 @@ public static function base64Decode(string $str): string * @return string * @throws TypeError */ - public static function base64EncodeDotSlash(string $str): string - { + public static function base64EncodeDotSlash( + #[\SensitiveParameter] + string $str + ): string { return Base64DotSlash::encode($str); } @@ -176,8 +198,10 @@ public static function base64EncodeDotSlash(string $str): string * @throws \RangeException * @throws TypeError */ - public static function base64DecodeDotSlash(string $str): string - { + public static function base64DecodeDotSlash( + #[\SensitiveParameter] + string $str + ): string { return Base64DotSlash::decode($str); } @@ -189,8 +213,10 @@ public static function base64DecodeDotSlash(string $str): string * @return string * @throws TypeError */ - public static function base64EncodeDotSlashOrdered(string $str): string - { + public static function base64EncodeDotSlashOrdered( + #[\SensitiveParameter] + string $str + ): string { return Base64DotSlashOrdered::encode($str); } @@ -204,8 +230,10 @@ public static function base64EncodeDotSlashOrdered(string $str): string * @throws \RangeException * @throws TypeError */ - public static function base64DecodeDotSlashOrdered(string $str): string - { + public static function base64DecodeDotSlashOrdered( + #[\SensitiveParameter] + string $str + ): string { return Base64DotSlashOrdered::decode($str); } @@ -217,8 +245,10 @@ public static function base64DecodeDotSlashOrdered(string $str): string * @return string * @throws TypeError */ - public static function hexEncode(string $bin_string): string - { + public static function hexEncode( + #[\SensitiveParameter] + string $bin_string + ): string { return Hex::encode($bin_string); } @@ -230,8 +260,10 @@ public static function hexEncode(string $bin_string): string * @return string (raw binary) * @throws \RangeException */ - public static function hexDecode(string $hex_string): string - { + public static function hexDecode( + #[\SensitiveParameter] + string $hex_string + ): string { return Hex::decode($hex_string); } @@ -243,8 +275,10 @@ public static function hexDecode(string $hex_string): string * @return string * @throws TypeError */ - public static function hexEncodeUpper(string $bin_string): string - { + public static function hexEncodeUpper( + #[\SensitiveParameter] + string $bin_string + ): string { return Hex::encodeUpper($bin_string); } @@ -255,8 +289,10 @@ public static function hexEncodeUpper(string $bin_string): string * @param string $bin_string (raw binary) * @return string */ - public static function hexDecodeUpper(string $bin_string): string - { + public static function hexDecodeUpper( + #[\SensitiveParameter] + string $bin_string + ): string { return Hex::decode($bin_string); } } diff --git a/vendor/paragonie/constant_time_encoding/src/Hex.php b/vendor/paragonie/constant_time_encoding/src/Hex.php index a9e058c..97c2046 100644 --- a/vendor/paragonie/constant_time_encoding/src/Hex.php +++ b/vendor/paragonie/constant_time_encoding/src/Hex.php @@ -42,8 +42,10 @@ abstract class Hex implements EncoderInterface * @return string * @throws TypeError */ - public static function encode(string $binString): string - { + public static function encode( + #[\SensitiveParameter] + string $binString + ): string { $hex = ''; $len = Binary::safeStrlen($binString); for ($i = 0; $i < $len; ++$i) { @@ -69,8 +71,10 @@ public static function encode(string $binString): string * @return string * @throws TypeError */ - public static function encodeUpper(string $binString): string - { + public static function encodeUpper( + #[\SensitiveParameter] + string $binString + ): string { $hex = ''; $len = Binary::safeStrlen($binString); @@ -99,6 +103,7 @@ public static function encodeUpper(string $binString): string * @throws RangeException */ public static function decode( + #[\SensitiveParameter] string $encodedString, bool $strictPadding = false ): string { diff --git a/vendor/paragonie/constant_time_encoding/src/RFC4648.php b/vendor/paragonie/constant_time_encoding/src/RFC4648.php index f124d65..7cd2e99 100644 --- a/vendor/paragonie/constant_time_encoding/src/RFC4648.php +++ b/vendor/paragonie/constant_time_encoding/src/RFC4648.php @@ -46,8 +46,10 @@ abstract class RFC4648 * * @throws TypeError */ - public static function base64Encode(string $str): string - { + public static function base64Encode( + #[\SensitiveParameter] + string $str + ): string { return Base64::encode($str); } @@ -61,8 +63,10 @@ public static function base64Encode(string $str): string * * @throws TypeError */ - public static function base64Decode(string $str): string - { + public static function base64Decode( + #[\SensitiveParameter] + string $str + ): string { return Base64::decode($str, true); } @@ -76,8 +80,10 @@ public static function base64Decode(string $str): string * * @throws TypeError */ - public static function base64UrlSafeEncode(string $str): string - { + public static function base64UrlSafeEncode( + #[\SensitiveParameter] + string $str + ): string { return Base64UrlSafe::encode($str); } @@ -91,8 +97,10 @@ public static function base64UrlSafeEncode(string $str): string * * @throws TypeError */ - public static function base64UrlSafeDecode(string $str): string - { + public static function base64UrlSafeDecode( + #[\SensitiveParameter] + string $str + ): string { return Base64UrlSafe::decode($str, true); } @@ -106,8 +114,10 @@ public static function base64UrlSafeDecode(string $str): string * * @throws TypeError */ - public static function base32Encode(string $str): string - { + public static function base32Encode( + #[\SensitiveParameter] + string $str + ): string { return Base32::encodeUpper($str); } @@ -121,8 +131,10 @@ public static function base32Encode(string $str): string * * @throws TypeError */ - public static function base32Decode(string $str): string - { + public static function base32Decode( + #[\SensitiveParameter] + string $str + ): string { return Base32::decodeUpper($str, true); } @@ -136,8 +148,10 @@ public static function base32Decode(string $str): string * * @throws TypeError */ - public static function base32HexEncode(string $str): string - { + public static function base32HexEncode( + #[\SensitiveParameter] + string $str + ): string { return Base32::encodeUpper($str); } @@ -151,8 +165,10 @@ public static function base32HexEncode(string $str): string * * @throws TypeError */ - public static function base32HexDecode(string $str): string - { + public static function base32HexDecode( + #[\SensitiveParameter] + string $str + ): string { return Base32::decodeUpper($str, true); } @@ -166,8 +182,10 @@ public static function base32HexDecode(string $str): string * * @throws TypeError */ - public static function base16Encode(string $str): string - { + public static function base16Encode( + #[\SensitiveParameter] + string $str + ): string { return Hex::encodeUpper($str); } @@ -179,8 +197,10 @@ public static function base16Encode(string $str): string * @param string $str * @return string */ - public static function base16Decode(string $str): string - { + public static function base16Decode( + #[\SensitiveParameter] + string $str + ): string { return Hex::decode($str, true); } -} \ No newline at end of file +} diff --git a/vendor/paragonie/csp-builder/src/CSPBuilder.php b/vendor/paragonie/csp-builder/src/CSPBuilder.php index de71cd9..544121d 100644 --- a/vendor/paragonie/csp-builder/src/CSPBuilder.php +++ b/vendor/paragonie/csp-builder/src/CSPBuilder.php @@ -2,6 +2,9 @@ declare(strict_types=1); namespace ParagonIE\CSPBuilder; +use Opis\JsonSchema\Exceptions\SchemaException; +use Opis\JsonSchema\Helper; +use Opis\JsonSchema\Validator; use ParagonIE\ConstantTime\Base64; use Psr\Http\Message\MessageInterface; use Exception; @@ -56,6 +59,21 @@ class CSPBuilder */ private $compiled = ''; + /** + * @var array + */ + private $reportEndpoints = []; + + /** + * @var string + */ + private $compiledEndpoints = ''; + + /** + * @var bool + */ + private $needsCompileEndpoints = true; + /** * @var bool */ @@ -141,13 +159,17 @@ public function compile(): string if (!is_string($this->policies['report-uri'])) { throw new TypeError('report-uri policy somehow not a string'); } - $compiled [] = 'report-uri ' . $this->enc($this->policies['report-uri'], 'report-uri') . '; '; + $compiled []= sprintf( + 'report-uri %s; ', + $this->enc($this->policies['report-uri'], 'report-uri') + ); } if (!empty($this->policies['report-to'])) { if (!is_string($this->policies['report-to'])) { throw new TypeError('report-to policy somehow not a string'); } - $compiled []= 'report-to ' . $this->policies['report-to'] . '; '; + // @todo validate this `report-to` target, is in the `report-to` header? + $compiled[] = sprintf('report-to %s; ', $this->policies['report-to']); } if (!empty($this->policies['upgrade-insecure-requests'])) { $compiled []= 'upgrade-insecure-requests'; @@ -155,9 +177,39 @@ public function compile(): string $this->compiled = rtrim(implode('', $compiled), '; '); $this->needsCompile = false; + return $this->compiled; } + /** + * @psalm-suppress DocblockTypeContradiction + * @psalm-suppress TypeDoesNotContainType + */ + public function compileReportEndpoints(): string + { + if (!empty($this->reportEndpoints) && $this->needsCompileEndpoints) { + // If it's a string, it's probably something like `report-to: key=endpoint + // Do nothing + if (!is_array($this->reportEndpoints)) { + throw new TypeError('Report endpoints is not an array'); + } + + $jsonValidator = new Validator(); + $reportTo = []; + $schema = file_get_contents(__DIR__ . '/../schema/reportto.json'); + foreach ($this->reportEndpoints as $reportEndpoint) { + $reportEndpointAsJSON = \Opis\JsonSchema\Helper::toJSON($reportEndpoint); + $isValid = $jsonValidator->validate($reportEndpointAsJSON, $schema); + if ($isValid->isValid()) { + $reportTo[] = json_encode($reportEndpointAsJSON); + } + } + $this->compiledEndpoints = rtrim(implode(',', $reportTo)); + $this->needsCompileEndpoints = false; + } + return $this->compiledEndpoints; + } + /** * Add a source to our allow white-list * @@ -171,6 +223,14 @@ public function addSource(string $directive, string $path): self $this->needsCompile = true; switch ($directive) { case 'child': + case 'child-src': + if ($this->supportOldBrowsers) { + $this->policies['child-src']['allow'][] = $path; + $this->policies['frame-src']['allow'][] = $path; + return $this; + } + $directive = 'child-src'; + break; case 'frame': case 'frame-src': if ($this->supportOldBrowsers) { @@ -178,7 +238,7 @@ public function addSource(string $directive, string $path): self $this->policies['frame-src']['allow'][] = $path; return $this; } - $directive = 'child-src'; + $directive = 'frame-src'; break; case 'connect': case 'socket': @@ -229,8 +289,10 @@ public function addSource(string $directive, string $path): self if (!isset($this->policies[$directive]['allow'])) { $this->policies[$directive]['allow'] = []; } - if (!in_array($path, $this->policies[$directive]['allow'], true)) { - $this->policies[$directive]['allow'][] = $path; + if (is_array($this->policies[$directive]['allow'])) { + if (!in_array($path, $this->policies[$directive]['allow'], true)) { + $this->policies[$directive]['allow'][] = $path; + } } return $this; } @@ -258,6 +320,17 @@ public function addDirective(string $key, $value = null): self return $this; } + + /** + * @param array|string $reportEndpoint + * @return void + */ + public function addReportEndpoints($reportEndpoint): void + { + $this->needsCompileEndpoints = true; + $this->reportEndpoints[] = Helper::toJSON($reportEndpoint); + } + /** * Add a plugin type to be added * @@ -347,6 +420,72 @@ public static function fromFile(string $filename = ''): self return self::fromData($contents); } + /** + * Factory method - create a new CSPBuilder object from an existing CSP header + * + * @param string $header + * @return self + * @throws Exception + * + * @psalm-suppress DocblockTypeContradiction + */ + public static function fromHeader(string $header = ''): self + { + $csp = new CSPBuilder(); + + $directives = explode(';', $header); + + foreach ($directives as $directive) { + [$name, $values] = explode(' ', trim($directive), 2) + [null, null]; + + if (is_null($name)) { + continue; + } + + if ('upgrade-insecure-requests' === $name) { + $csp->addDirective('upgrade-insecure-requests'); + + continue; + } + + if (null === $values) { + continue; + } + + foreach (explode(' ', $values) as $value) { + if ('report-to' === $name) { + $csp->setReportTo($value); + } elseif ('report-uri' === $name) { + $csp->setReportUri($value); + } elseif ('require-sri-for' === $name) { + $csp->requireSRIFor($value); + } elseif ('plugin-types' === $name) { + $csp->allowPluginType($value); + } else { + switch ($value) { + case "'none'": $csp->addDirective($name, false); break; + case "'self'": $csp->setSelfAllowed($name, true); break; + case 'blob:': $csp->setBlobAllowed($name, true); break; + case 'data:': $csp->setDataAllowed($name, true); break; + case 'filesystem:': $csp->setFileSystemAllowed($name, true); break; + case 'https:': $csp->setHttpsAllowed($name, true); break; + case 'mediastream:': $csp->setMediaStreamAllowed($name, true); break; + case "'report-sample'": $csp->setReportSample($name, true); break; + case "'strict-dynamic'": $csp->setStrictDynamic($name, true); break; + case "'unsafe-eval'": $csp->setAllowUnsafeEval($name, true); break; + case "'unsafe-hashes'": $csp->setAllowUnsafeHashes($name, true); break; + case "'unsafe-inline'": $csp->setAllowUnsafeInline($name, true); break; + case "'unsafe-hashed-attributes'": $csp->setAllowUnsafeHashedAttributes('script-src', true); break; + + default: $csp->addSource($name, $value); + } + } + } + } + + return $csp; + } + /** * Get the formatted CSP header * @@ -360,6 +499,20 @@ public function getCompiledHeader(): string return $this->compiled; } + /** + * Get the formatted report-to header + * + * @return string + */ + public function getCompiledReportEndpointsHeader(): string + { + if ($this->needsCompileEndpoints) { + $this->compileReportEndpoints(); + } + + return $this->compiledEndpoints; + } + /** * Get an associative array of headers to return. * @@ -368,10 +521,18 @@ public function getCompiledHeader(): string */ public function getHeaderArray(bool $legacy = true): array { + $return = []; if ($this->needsCompile) { $this->compile(); } - $return = []; + if ($this->needsCompileEndpoints) { + $this->compileReportEndpoints(); + } + if (!empty($this->compiledEndpoints)) { + $return = [ + 'Report-To' => $this->compiledEndpoints + ]; + } foreach ($this->getHeaderKeys($legacy) as $key) { $return[(string) $key] = $this->compiled; } @@ -393,6 +554,14 @@ public function getRequireHeaders(): array return $headers; } + /** + * @return array + */ + public function getReportEndpoints(): array + { + return $this->reportEndpoints; + } + /** * Add a new hash to the existing CSP * @@ -433,6 +602,9 @@ public function injectCSPHeader(MessageInterface $message, bool $legacy = false) if ($this->needsCompile) { $this->compile(); } + if ($this->needsCompileEndpoints) { + $this->compileReportEndpoints(); + } foreach ($this->getRequireHeaders() as $header) { list ($key, $value) = $header; $message = $message->withAddedHeader($key, $value); @@ -440,6 +612,10 @@ public function injectCSPHeader(MessageInterface $message, bool $legacy = false) foreach ($this->getHeaderKeys($legacy) as $key) { $message = $message->withAddedHeader($key, $this->compiled); } + if (!empty($this->compileReportEndpoints())) { + $message = $message->withAddedHeader('report-to', $this->compiledEndpoints); + } + return $message; } @@ -454,7 +630,7 @@ public function injectCSPHeader(MessageInterface $message, bool $legacy = false) public function nonce(string $directive = 'script-src', string $nonce = ''): string { $ruleKeys = array_keys($this->policies); - if (!in_array($directive, $ruleKeys)) { + if (!in_array($directive, $ruleKeys) && !in_array('default-src', $ruleKeys)) { return ''; } @@ -514,6 +690,7 @@ public function saveSnippet( ): bool { if ($this->needsCompile) { $this->compile(); + $this->compileReportEndpoints(); } // Are we doing a report-only header? @@ -570,12 +747,18 @@ public function sendCSPHeader(bool $legacy = true): bool if ($this->needsCompile) { $this->compile(); } + if ($this->needsCompileEndpoints) { + $this->compileReportEndpoints(); + } foreach ($this->getRequireHeaders() as $header) { list ($key, $value) = $header; - header($key.': '.$value); + header(sprintf('%s: %s', $key, $value)); } foreach ($this->getHeaderKeys($legacy) as $key) { - header($key.': '.$this->compiled); + header(sprintf('%s: %s', $key, $this->compiled)); + } + if (!empty($this->compiledEndpoints)) { + header(sprintf('report-to: %s', $this->compiledEndpoints)); } return true; } @@ -698,6 +881,34 @@ public function removeDirective(string $key): self return $this; } + /** + * @param array|string $reportEndpoints + * @return void + */ + public function setReportEndpoints($reportEndpoints): void + { + $this->needsCompileEndpoints = true; + $toJSON = Helper::toJSON($reportEndpoints); + // If there's only one, wrap it in an array, so more can be added + $toJSON = is_array($toJSON) ? $toJSON : [$toJSON]; + $this->reportEndpoints = $toJSON; + } + + /** + * @param string $key + * @return void + */ + public function removeReportEndpoint(string $key): void + { + foreach ($this->reportEndpoints as $idx => $endpoint) { + if ($endpoint->group === $key) { + unset($this->reportEndpoints[$idx]); + // Reset the array keys + $this->reportEndpoints = array_values($this->reportEndpoints); + break; + } + } + } /** * Allow/disallow filesystem: URIs for a given directive * @@ -855,10 +1066,10 @@ public function setReportUri(string $url = ''): self /** * Set the report-to directive to the desired string. * - * @param string $policy + * @param string|array $policy * @return self */ - public function setReportTo(string $policy = ''): self + public function setReportTo($policy = ''): self { $this->policies['report-to'] = $policy; return $this; @@ -900,7 +1111,7 @@ protected function compileSubgroup(string $directive, $policies = []): string if (!empty($policies['allow'])) { /** @var array $allowedPolicies */ $allowedPolicies = $policies['allow']; - foreach ($allowedPolicies as $url) { + foreach (array_unique($allowedPolicies) as $url) { /** @var string|bool $url */ $url = filter_var($url, FILTER_SANITIZE_URL); if (is_string($url)) { @@ -1059,6 +1270,7 @@ protected function enc(string $piece, string $type = 'default'): string * Is this user currently connected over HTTPS? * * @return bool + * @psalm-suppress RiskyTruthyFalsyComparison */ protected function isHTTPSConnection(): bool {