diff --git a/composer.json b/composer.json index b75ec8985..ec1d51244 100644 --- a/composer.json +++ b/composer.json @@ -15,8 +15,6 @@ "apereo/phpcas": "~1.6.0", "firebase/php-jwt": "^6.4.0", "guzzlehttp/guzzle": "^7.5.1", - "laminas/laminas-mail": "^2.11", - "laminas/laminas-servicemanager": "^3.5", "league/oauth2-google": "^4.0.1", "nikic/php-parser": "^4.14.0", "pear/archive_tar": "~1.4.14", @@ -32,6 +30,7 @@ "symfony/twig-bundle": "~6.4.0", "symfony/var-dumper": "~6.4.0", "symfony/yaml": "~6.4.0", + "symfony/mailer": "~6.4.0", "tecnickcom/tcpdf": "^6.6.0", "thenetworg/oauth2-azure": "^2.0", "soundasleep/html2text": "~2.1" diff --git a/composer.lock b/composer.lock index eb6a815f2..d2d5c710b 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": "18d0c769ec5c249b96e3be8f168bbb11", + "content-hash": "0da5da3b165955f386268e6dd8db2a8d", "packages": [ { "name": "apereo/phpcas", @@ -77,6 +77,150 @@ }, "time": "2023-02-19T19:52:35+00:00" }, + { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "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": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2025-03-06T22:45:56+00:00" + }, { "name": "firebase/php-jwt", "version": "v6.10.0", @@ -465,434 +609,6 @@ ], "time": "2023-12-03T20:05:35+00:00" }, - { - "name": "laminas/laminas-loader", - "version": "2.10.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-loader.git", - "reference": "e6fe952304ef40ce45cd814751ab35d42afdad12" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/e6fe952304ef40ce45cd814751ab35d42afdad12", - "reference": "e6fe952304ef40ce45cd814751ab35d42afdad12", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-loader": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "~9.5.25" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Loader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Autoloading and plugin loading strategies", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "loader" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-loader/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-loader/issues", - "rss": "https://github.com/laminas/laminas-loader/releases.atom", - "source": "https://github.com/laminas/laminas-loader" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-10-18T09:58:51+00:00" - }, - { - "name": "laminas/laminas-mail", - "version": "2.22.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-mail.git", - "reference": "1d307ff65328c00117c6d90ba0084fdd0fc2bd5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-mail/zipball/1d307ff65328c00117c6d90ba0084fdd0fc2bd5c", - "reference": "1d307ff65328c00117c6d90ba0084fdd0fc2bd5c", - "shasum": "" - }, - "require": { - "ext-iconv": "*", - "laminas/laminas-loader": "^2.8.0", - "laminas/laminas-mime": "^2.10.0", - "laminas/laminas-stdlib": "^3.11.0", - "laminas/laminas-validator": "^2.23.0", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "symfony/polyfill-intl-idn": "^1.26.0", - "symfony/polyfill-mbstring": "^1.16.0", - "webmozart/assert": "^1.11.0" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-crypt": "^3.9.0", - "laminas/laminas-db": "^2.16", - "laminas/laminas-servicemanager": "^3.20", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.4", - "symfony/process": "^6.0.11", - "vimeo/psalm": "^5.1" - }, - "suggest": { - "laminas/laminas-crypt": "^3.8 Crammd5 support in SMTP Auth", - "laminas/laminas-servicemanager": "^3.16 when using SMTP to deliver messages" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Mail", - "config-provider": "Laminas\\Mail\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Mail\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "mail" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-mail/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-mail/issues", - "rss": "https://github.com/laminas/laminas-mail/releases.atom", - "source": "https://github.com/laminas/laminas-mail" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-01-18T08:33:48+00:00" - }, - { - "name": "laminas/laminas-mime", - "version": "2.12.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-mime.git", - "reference": "08cc544778829b7d68d27a097885bd6e7130135e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-mime/zipball/08cc544778829b7d68d27a097885bd6e7130135e", - "reference": "08cc544778829b7d68d27a097885bd6e7130135e", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^2.7 || ^3.0", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-mime": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-mail": "^2.19.0", - "phpunit/phpunit": "~9.5.25" - }, - "suggest": { - "laminas/laminas-mail": "Laminas\\Mail component" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Mime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Create and parse MIME messages and parts", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "mime" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-mime/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-mime/issues", - "rss": "https://github.com/laminas/laminas-mime/releases.atom", - "source": "https://github.com/laminas/laminas-mime" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-11-02T16:47:19+00:00" - }, - { - "name": "laminas/laminas-servicemanager", - "version": "3.22.1", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "de98d297d4743956a0558a6d71616979ff779328" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/de98d297d4743956a0558a6d71616979ff779328", - "reference": "de98d297d4743956a0558a6d71616979ff779328", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.17", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "psr/container": "^1.0" - }, - "conflict": { - "ext-psr": "*", - "laminas/laminas-code": "<4.10.0", - "zendframework/zend-code": "<3.3.1", - "zendframework/zend-servicemanager": "*" - }, - "provide": { - "psr/container-implementation": "^1.0" - }, - "replace": { - "container-interop/container-interop": "^1.2.0" - }, - "require-dev": { - "composer/package-versions-deprecated": "^1.11.99.5", - "friendsofphp/proxy-manager-lts": "^1.0.14", - "laminas/laminas-code": "^4.10.0", - "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-container-config-test": "^0.8", - "mikey179/vfsstream": "^1.6.11", - "phpbench/phpbench": "^1.2.9", - "phpunit/phpunit": "^10.4", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.8.0" - }, - "suggest": { - "friendsofphp/proxy-manager-lts": "ProxyManager ^2.1.1 to handle lazy initialization of services" - }, - "bin": [ - "bin/generate-deps-for-config-factory", - "bin/generate-factory-for-class" - ], - "type": "library", - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Laminas\\ServiceManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Factory-Driven Dependency Injection Container", - "homepage": "https://laminas.dev", - "keywords": [ - "PSR-11", - "dependency-injection", - "di", - "dic", - "laminas", - "service-manager", - "servicemanager" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-servicemanager/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-servicemanager/issues", - "rss": "https://github.com/laminas/laminas-servicemanager/releases.atom", - "source": "https://github.com/laminas/laminas-servicemanager" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-10-24T11:19:47+00:00" - }, - { - "name": "laminas/laminas-stdlib", - "version": "3.19.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "6a192dd0882b514e45506f533b833b623b78fff3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/6a192dd0882b514e45506f533b833b623b78fff3", - "reference": "6a192dd0882b514e45506f533b833b623b78fff3", - "shasum": "" - }, - "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-stdlib": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.5", - "phpbench/phpbench": "^1.2.15", - "phpunit/phpunit": "^10.5.8", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.20.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Stdlib\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "SPL extensions, array utilities, error handlers, and more", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "stdlib" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-stdlib/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-stdlib/issues", - "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", - "source": "https://github.com/laminas/laminas-stdlib" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2024-01-19T12:39:49+00:00" - }, - { - "name": "laminas/laminas-validator", - "version": "2.27.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-validator.git", - "reference": "451f5e24574a99b86e8e22f0431ccfc6d5c7318b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/451f5e24574a99b86e8e22f0431ccfc6d5c7318b", - "reference": "451f5e24574a99b86e8e22f0431ccfc6d5c7318b", - "shasum": "" - }, - "require": { - "laminas/laminas-servicemanager": "^3.12.0", - "laminas/laminas-stdlib": "^3.13", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-validator": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "laminas/laminas-db": "^2.15.0", - "laminas/laminas-filter": "^2.23.0", - "laminas/laminas-http": "^2.17.0", - "laminas/laminas-i18n": "^2.19", - "laminas/laminas-session": "^2.13.0", - "laminas/laminas-uri": "^2.10.0", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.18.0", - "psr/http-client": "^1.0.1", - "psr/http-factory": "^1.0.1", - "psr/http-message": "^1.0.1", - "vimeo/psalm": "^4.28" - }, - "suggest": { - "laminas/laminas-db": "Laminas\\Db component, required by the (No)RecordExists validator", - "laminas/laminas-filter": "Laminas\\Filter component, required by the Digits validator", - "laminas/laminas-i18n": "Laminas\\I18n component to allow translation of validation error messages", - "laminas/laminas-i18n-resources": "Translations of validator messages", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", - "laminas/laminas-session": "Laminas\\Session component, ^2.8; required by the Csrf validator", - "laminas/laminas-uri": "Laminas\\Uri component, required by the Uri and Sitemap\\Loc validators", - "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Validator", - "config-provider": "Laminas\\Validator\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Validator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "validator" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-validator/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-validator/issues", - "rss": "https://github.com/laminas/laminas-validator/releases.atom", - "source": "https://github.com/laminas/laminas-validator" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-11-12T21:00:53+00:00" - }, { "name": "league/oauth2-client", "version": "2.7.0", @@ -2518,16 +2234,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { @@ -2535,12 +2251,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -2565,7 +2281,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { @@ -2581,7 +2297,7 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/dotenv", @@ -2734,16 +2450,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v6.4.2", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "e95216850555cd55e71b857eb9d6c2674124603a" + "reference": "b0cf3162020603587363f0551cd3be43958611ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e95216850555cd55e71b857eb9d6c2674124603a", - "reference": "e95216850555cd55e71b857eb9d6c2674124603a", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b0cf3162020603587363f0551cd3be43958611ff", + "reference": "b0cf3162020603587363f0551cd3be43958611ff", "shasum": "" }, "require": { @@ -2794,7 +2510,7 @@ "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": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.25" }, "funding": [ { @@ -2805,25 +2521,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2023-12-27T22:16:42+00:00" + "time": "2025-08-13T09:41:44+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", "shasum": "" }, "require": { @@ -2832,12 +2552,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -2870,7 +2590,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" }, "funding": [ { @@ -2886,7 +2606,7 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/filesystem", @@ -3353,6 +3073,179 @@ ], "time": "2023-12-30T15:31:44+00:00" }, + { + "name": "symfony/mailer", + "version": "v6.4.25", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/628b43b45a3e6b15c8a633fb22df547ed9b492a2", + "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.1", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/messenger": "<6.2", + "symfony/mime": "<6.2", + "symfony/twig-bridge": "<6.2.1" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.2|^7.0", + "symfony/twig-bridge": "^6.2|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.4.25" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-08-13T09:41:44+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.4.24", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/664d5e844a2de5e11c8255d0aef6bc15a9660ac7", + "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "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": "<5.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "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": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.4.24" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T12:02:45+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.28.0", @@ -3518,34 +3411,30 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.28.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3585,7 +3474,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" }, "funding": [ { @@ -3596,41 +3485,42 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2023-01-26T09:30:37+00:00" + "time": "2024-09-10T14:38:51+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3669,7 +3559,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" }, "funding": [ { @@ -3680,29 +3570,34 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -3712,12 +3607,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3752,7 +3644,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -3764,79 +3656,7 @@ "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-07-28T09:04:16+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "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\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/nicolas-grekas", "type": "github" }, { @@ -3844,33 +3664,30 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.28.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3911,7 +3728,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" }, "funding": [ { @@ -3922,12 +3739,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2025-01-02T08:10:11+00:00" }, { "name": "symfony/polyfill-php83", @@ -4177,33 +3998,34 @@ }, { "name": "symfony/service-contracts", - "version": "v3.4.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -4239,7 +4061,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" }, "funding": [ { @@ -4255,7 +4077,7 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2025-04-25T09:37:31+00:00" }, { "name": "symfony/string", @@ -5055,64 +4877,6 @@ } ], "time": "2025-05-03T07:21:55+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" } ], "packages-dev": [ diff --git a/core/email.class.inc.php b/core/email.class.inc.php index d929cb887..ca26d9223 100644 --- a/core/email.class.inc.php +++ b/core/email.class.inc.php @@ -114,9 +114,6 @@ class EMail implements iEMail * @param string $sSerializedMessage The serialized representation of the message * * @return \Email - * @throws \ArchivedObjectException - * @throws \CoreException - * @throws \Symfony\Component\CssSelector\Exception\SyntaxErrorException */ public static function UnSerializeV2($sSerializedMessage) { diff --git a/lib/bin/generate-deps-for-config-factory b/lib/bin/generate-deps-for-config-factory deleted file mode 100644 index 7b9886356..000000000 --- a/lib/bin/generate-deps-for-config-factory +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if ( - (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) - || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) - ) { - return include("phpvfscomposer://" . __DIR__ . '/..'.'/laminas/laminas-servicemanager/bin/generate-deps-for-config-factory'); - } -} - -return include __DIR__ . '/..'.'/laminas/laminas-servicemanager/bin/generate-deps-for-config-factory'; diff --git a/lib/bin/generate-deps-for-config-factory.bat b/lib/bin/generate-deps-for-config-factory.bat deleted file mode 100644 index 633ccd730..000000000 --- a/lib/bin/generate-deps-for-config-factory.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/generate-deps-for-config-factory -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/bin/generate-factory-for-class b/lib/bin/generate-factory-for-class deleted file mode 100644 index 4bc576d42..000000000 --- a/lib/bin/generate-factory-for-class +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if ( - (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) - || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) - ) { - return include("phpvfscomposer://" . __DIR__ . '/..'.'/laminas/laminas-servicemanager/bin/generate-factory-for-class'); - } -} - -return include __DIR__ . '/..'.'/laminas/laminas-servicemanager/bin/generate-factory-for-class'; diff --git a/lib/bin/generate-factory-for-class.bat b/lib/bin/generate-factory-for-class.bat deleted file mode 100644 index 8fbef95e3..000000000 --- a/lib/bin/generate-factory-for-class.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/generate-factory-for-class -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 5ebc701f9..00d8c02a6 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -413,11 +413,12 @@ return array( 'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderAzure' => $baseDir . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAzure.php', 'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderFactory' => $baseDir . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderFactory.php', 'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderGoogle' => $baseDir . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php', - 'Combodo\\iTop\\Core\\Authentication\\Client\\Smtp\\Oauth' => $baseDir . '/sources/Core/Authentication/Client/Smtp/Oauth.php', 'Combodo\\iTop\\Core\\CMDBChange\\CMDBChangeOrigin' => $baseDir . '/sources/Core/CMDBChange/CMDBChangeOrigin.php', 'Combodo\\iTop\\Core\\DbConnectionWrapper' => $baseDir . '/core/DbConnectionWrapper.php', - 'Combodo\\iTop\\Core\\Email\\EMailLaminas' => $baseDir . '/sources/Core/Email/EmailLaminas.php', + 'Combodo\\iTop\\Core\\Email\\EMailSymfony' => $baseDir . '/sources/Core/Email/EmailSymfony.php', 'Combodo\\iTop\\Core\\Email\\EmailFactory' => $baseDir . '/sources/Core/Email/EmailFactory.php', + 'Combodo\\iTop\\Core\\Email\\Transport\\SymfonyFileTransport' => $baseDir . '/sources/Core/Email/Transport/SymfonyFileTransport.php', + 'Combodo\\iTop\\Core\\Email\\Transport\\SymfonyOAuthTransport' => $baseDir . '/sources/Core/Email/Transport/SymfonyOAuthTransport.php', 'Combodo\\iTop\\Core\\Email\\iEMail' => $baseDir . '/sources/Core/Email/iEMail.php', 'Combodo\\iTop\\Core\\EventListener\\AttributeBlobEventListener' => $baseDir . '/sources/Core/EventListener/AttributeBlobEventListener.php', 'Combodo\\iTop\\Core\\Kpi\\KpiLogData' => $baseDir . '/sources/Core/Kpi/KpiLogData.php', @@ -619,7 +620,96 @@ return array( 'DisplayableGroupNode' => $baseDir . '/core/displayablegraph.class.inc.php', 'DisplayableNode' => $baseDir . '/core/displayablegraph.class.inc.php', 'DisplayableRedundancyNode' => $baseDir . '/core/displayablegraph.class.inc.php', + 'Doctrine\\Common\\Lexer\\AbstractLexer' => $vendorDir . '/doctrine/lexer/src/AbstractLexer.php', + 'Doctrine\\Common\\Lexer\\Token' => $vendorDir . '/doctrine/lexer/src/Token.php', 'EMail' => $baseDir . '/core/email.class.inc.php', + 'Egulias\\EmailValidator\\EmailLexer' => $vendorDir . '/egulias/email-validator/src/EmailLexer.php', + 'Egulias\\EmailValidator\\EmailParser' => $vendorDir . '/egulias/email-validator/src/EmailParser.php', + 'Egulias\\EmailValidator\\EmailValidator' => $vendorDir . '/egulias/email-validator/src/EmailValidator.php', + 'Egulias\\EmailValidator\\MessageIDParser' => $vendorDir . '/egulias/email-validator/src/MessageIDParser.php', + 'Egulias\\EmailValidator\\Parser' => $vendorDir . '/egulias/email-validator/src/Parser.php', + 'Egulias\\EmailValidator\\Parser\\Comment' => $vendorDir . '/egulias/email-validator/src/Parser/Comment.php', + 'Egulias\\EmailValidator\\Parser\\CommentStrategy\\CommentStrategy' => $vendorDir . '/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php', + 'Egulias\\EmailValidator\\Parser\\CommentStrategy\\DomainComment' => $vendorDir . '/egulias/email-validator/src/Parser/CommentStrategy/DomainComment.php', + 'Egulias\\EmailValidator\\Parser\\CommentStrategy\\LocalComment' => $vendorDir . '/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php', + 'Egulias\\EmailValidator\\Parser\\DomainLiteral' => $vendorDir . '/egulias/email-validator/src/Parser/DomainLiteral.php', + 'Egulias\\EmailValidator\\Parser\\DomainPart' => $vendorDir . '/egulias/email-validator/src/Parser/DomainPart.php', + 'Egulias\\EmailValidator\\Parser\\DoubleQuote' => $vendorDir . '/egulias/email-validator/src/Parser/DoubleQuote.php', + 'Egulias\\EmailValidator\\Parser\\FoldingWhiteSpace' => $vendorDir . '/egulias/email-validator/src/Parser/FoldingWhiteSpace.php', + 'Egulias\\EmailValidator\\Parser\\IDLeftPart' => $vendorDir . '/egulias/email-validator/src/Parser/IDLeftPart.php', + 'Egulias\\EmailValidator\\Parser\\IDRightPart' => $vendorDir . '/egulias/email-validator/src/Parser/IDRightPart.php', + 'Egulias\\EmailValidator\\Parser\\LocalPart' => $vendorDir . '/egulias/email-validator/src/Parser/LocalPart.php', + 'Egulias\\EmailValidator\\Parser\\PartParser' => $vendorDir . '/egulias/email-validator/src/Parser/PartParser.php', + 'Egulias\\EmailValidator\\Result\\InvalidEmail' => $vendorDir . '/egulias/email-validator/src/Result/InvalidEmail.php', + 'Egulias\\EmailValidator\\Result\\MultipleErrors' => $vendorDir . '/egulias/email-validator/src/Result/MultipleErrors.php', + 'Egulias\\EmailValidator\\Result\\Reason\\AtextAfterCFWS' => $vendorDir . '/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CRLFAtTheEnd' => $vendorDir . '/egulias/email-validator/src/Result/Reason/CRLFAtTheEnd.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CRLFX2' => $vendorDir . '/egulias/email-validator/src/Result/Reason/CRLFX2.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CRNoLF' => $vendorDir . '/egulias/email-validator/src/Result/Reason/CRNoLF.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CharNotAllowed' => $vendorDir . '/egulias/email-validator/src/Result/Reason/CharNotAllowed.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CommaInDomain' => $vendorDir . '/egulias/email-validator/src/Result/Reason/CommaInDomain.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CommentsInIDRight' => $vendorDir . '/egulias/email-validator/src/Result/Reason/CommentsInIDRight.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ConsecutiveAt' => $vendorDir . '/egulias/email-validator/src/Result/Reason/ConsecutiveAt.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ConsecutiveDot' => $vendorDir . '/egulias/email-validator/src/Result/Reason/ConsecutiveDot.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DetailedReason' => $vendorDir . '/egulias/email-validator/src/Result/Reason/DetailedReason.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DomainAcceptsNoMail' => $vendorDir . '/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DomainHyphened' => $vendorDir . '/egulias/email-validator/src/Result/Reason/DomainHyphened.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DomainTooLong' => $vendorDir . '/egulias/email-validator/src/Result/Reason/DomainTooLong.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DotAtEnd' => $vendorDir . '/egulias/email-validator/src/Result/Reason/DotAtEnd.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DotAtStart' => $vendorDir . '/egulias/email-validator/src/Result/Reason/DotAtStart.php', + 'Egulias\\EmailValidator\\Result\\Reason\\EmptyReason' => $vendorDir . '/egulias/email-validator/src/Result/Reason/EmptyReason.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExceptionFound' => $vendorDir . '/egulias/email-validator/src/Result/Reason/ExceptionFound.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExpectingATEXT' => $vendorDir . '/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExpectingCTEXT' => $vendorDir . '/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExpectingDTEXT' => $vendorDir . '/egulias/email-validator/src/Result/Reason/ExpectingDTEXT.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExpectingDomainLiteralClose' => $vendorDir . '/egulias/email-validator/src/Result/Reason/ExpectingDomainLiteralClose.php', + 'Egulias\\EmailValidator\\Result\\Reason\\LabelTooLong' => $vendorDir . '/egulias/email-validator/src/Result/Reason/LabelTooLong.php', + 'Egulias\\EmailValidator\\Result\\Reason\\LocalOrReservedDomain' => $vendorDir . '/egulias/email-validator/src/Result/Reason/LocalOrReservedDomain.php', + 'Egulias\\EmailValidator\\Result\\Reason\\NoDNSRecord' => $vendorDir . '/egulias/email-validator/src/Result/Reason/NoDNSRecord.php', + 'Egulias\\EmailValidator\\Result\\Reason\\NoDomainPart' => $vendorDir . '/egulias/email-validator/src/Result/Reason/NoDomainPart.php', + 'Egulias\\EmailValidator\\Result\\Reason\\NoLocalPart' => $vendorDir . '/egulias/email-validator/src/Result/Reason/NoLocalPart.php', + 'Egulias\\EmailValidator\\Result\\Reason\\RFCWarnings' => $vendorDir . '/egulias/email-validator/src/Result/Reason/RFCWarnings.php', + 'Egulias\\EmailValidator\\Result\\Reason\\Reason' => $vendorDir . '/egulias/email-validator/src/Result/Reason/Reason.php', + 'Egulias\\EmailValidator\\Result\\Reason\\SpoofEmail' => $vendorDir . '/egulias/email-validator/src/Result/Reason/SpoofEmail.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnOpenedComment' => $vendorDir . '/egulias/email-validator/src/Result/Reason/UnOpenedComment.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnableToGetDNSRecord' => $vendorDir . '/egulias/email-validator/src/Result/Reason/UnableToGetDNSRecord.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnclosedComment' => $vendorDir . '/egulias/email-validator/src/Result/Reason/UnclosedComment.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnclosedQuotedString' => $vendorDir . '/egulias/email-validator/src/Result/Reason/UnclosedQuotedString.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnusualElements' => $vendorDir . '/egulias/email-validator/src/Result/Reason/UnusualElements.php', + 'Egulias\\EmailValidator\\Result\\Result' => $vendorDir . '/egulias/email-validator/src/Result/Result.php', + 'Egulias\\EmailValidator\\Result\\SpoofEmail' => $vendorDir . '/egulias/email-validator/src/Result/SpoofEmail.php', + 'Egulias\\EmailValidator\\Result\\ValidEmail' => $vendorDir . '/egulias/email-validator/src/Result/ValidEmail.php', + 'Egulias\\EmailValidator\\Validation\\DNSCheckValidation' => $vendorDir . '/egulias/email-validator/src/Validation/DNSCheckValidation.php', + 'Egulias\\EmailValidator\\Validation\\DNSGetRecordWrapper' => $vendorDir . '/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php', + 'Egulias\\EmailValidator\\Validation\\DNSRecords' => $vendorDir . '/egulias/email-validator/src/Validation/DNSRecords.php', + 'Egulias\\EmailValidator\\Validation\\EmailValidation' => $vendorDir . '/egulias/email-validator/src/Validation/EmailValidation.php', + 'Egulias\\EmailValidator\\Validation\\Exception\\EmptyValidationList' => $vendorDir . '/egulias/email-validator/src/Validation/Exception/EmptyValidationList.php', + 'Egulias\\EmailValidator\\Validation\\Extra\\SpoofCheckValidation' => $vendorDir . '/egulias/email-validator/src/Validation/Extra/SpoofCheckValidation.php', + 'Egulias\\EmailValidator\\Validation\\MessageIDValidation' => $vendorDir . '/egulias/email-validator/src/Validation/MessageIDValidation.php', + 'Egulias\\EmailValidator\\Validation\\MultipleValidationWithAnd' => $vendorDir . '/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php', + 'Egulias\\EmailValidator\\Validation\\NoRFCWarningsValidation' => $vendorDir . '/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php', + 'Egulias\\EmailValidator\\Validation\\RFCValidation' => $vendorDir . '/egulias/email-validator/src/Validation/RFCValidation.php', + 'Egulias\\EmailValidator\\Warning\\AddressLiteral' => $vendorDir . '/egulias/email-validator/src/Warning/AddressLiteral.php', + 'Egulias\\EmailValidator\\Warning\\CFWSNearAt' => $vendorDir . '/egulias/email-validator/src/Warning/CFWSNearAt.php', + 'Egulias\\EmailValidator\\Warning\\CFWSWithFWS' => $vendorDir . '/egulias/email-validator/src/Warning/CFWSWithFWS.php', + 'Egulias\\EmailValidator\\Warning\\Comment' => $vendorDir . '/egulias/email-validator/src/Warning/Comment.php', + 'Egulias\\EmailValidator\\Warning\\DeprecatedComment' => $vendorDir . '/egulias/email-validator/src/Warning/DeprecatedComment.php', + 'Egulias\\EmailValidator\\Warning\\DomainLiteral' => $vendorDir . '/egulias/email-validator/src/Warning/DomainLiteral.php', + 'Egulias\\EmailValidator\\Warning\\EmailTooLong' => $vendorDir . '/egulias/email-validator/src/Warning/EmailTooLong.php', + 'Egulias\\EmailValidator\\Warning\\IPV6BadChar' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6BadChar.php', + 'Egulias\\EmailValidator\\Warning\\IPV6ColonEnd' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6ColonEnd.php', + 'Egulias\\EmailValidator\\Warning\\IPV6ColonStart' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6ColonStart.php', + 'Egulias\\EmailValidator\\Warning\\IPV6Deprecated' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6Deprecated.php', + 'Egulias\\EmailValidator\\Warning\\IPV6DoubleColon' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6DoubleColon.php', + 'Egulias\\EmailValidator\\Warning\\IPV6GroupCount' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6GroupCount.php', + 'Egulias\\EmailValidator\\Warning\\IPV6MaxGroups' => $vendorDir . '/egulias/email-validator/src/Warning/IPV6MaxGroups.php', + 'Egulias\\EmailValidator\\Warning\\LocalTooLong' => $vendorDir . '/egulias/email-validator/src/Warning/LocalTooLong.php', + 'Egulias\\EmailValidator\\Warning\\NoDNSMXRecord' => $vendorDir . '/egulias/email-validator/src/Warning/NoDNSMXRecord.php', + 'Egulias\\EmailValidator\\Warning\\ObsoleteDTEXT' => $vendorDir . '/egulias/email-validator/src/Warning/ObsoleteDTEXT.php', + 'Egulias\\EmailValidator\\Warning\\QuotedPart' => $vendorDir . '/egulias/email-validator/src/Warning/QuotedPart.php', + 'Egulias\\EmailValidator\\Warning\\QuotedString' => $vendorDir . '/egulias/email-validator/src/Warning/QuotedString.php', + 'Egulias\\EmailValidator\\Warning\\TLD' => $vendorDir . '/egulias/email-validator/src/Warning/TLD.php', + 'Egulias\\EmailValidator\\Warning\\Warning' => $vendorDir . '/egulias/email-validator/src/Warning/Warning.php', 'Event' => $baseDir . '/core/event.class.inc.php', 'EventIssue' => $baseDir . '/core/event.class.inc.php', 'EventLoginUsage' => $baseDir . '/core/event.class.inc.php', @@ -764,321 +854,6 @@ return array( 'JSButtonItem' => $baseDir . '/application/applicationextension.inc.php', 'JSPopupMenuItem' => $baseDir . '/application/applicationextension.inc.php', 'KeyValueStore' => $baseDir . '/core/counter.class.inc.php', - 'Laminas\\Loader\\AutoloaderFactory' => $vendorDir . '/laminas/laminas-loader/src/AutoloaderFactory.php', - 'Laminas\\Loader\\ClassMapAutoloader' => $vendorDir . '/laminas/laminas-loader/src/ClassMapAutoloader.php', - 'Laminas\\Loader\\Exception\\BadMethodCallException' => $vendorDir . '/laminas/laminas-loader/src/Exception/BadMethodCallException.php', - 'Laminas\\Loader\\Exception\\DomainException' => $vendorDir . '/laminas/laminas-loader/src/Exception/DomainException.php', - 'Laminas\\Loader\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-loader/src/Exception/ExceptionInterface.php', - 'Laminas\\Loader\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-loader/src/Exception/InvalidArgumentException.php', - 'Laminas\\Loader\\Exception\\InvalidPathException' => $vendorDir . '/laminas/laminas-loader/src/Exception/InvalidPathException.php', - 'Laminas\\Loader\\Exception\\MissingResourceNamespaceException' => $vendorDir . '/laminas/laminas-loader/src/Exception/MissingResourceNamespaceException.php', - 'Laminas\\Loader\\Exception\\PluginLoaderException' => $vendorDir . '/laminas/laminas-loader/src/Exception/PluginLoaderException.php', - 'Laminas\\Loader\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-loader/src/Exception/RuntimeException.php', - 'Laminas\\Loader\\Exception\\SecurityException' => $vendorDir . '/laminas/laminas-loader/src/Exception/SecurityException.php', - 'Laminas\\Loader\\ModuleAutoloader' => $vendorDir . '/laminas/laminas-loader/src/ModuleAutoloader.php', - 'Laminas\\Loader\\PluginClassLoader' => $vendorDir . '/laminas/laminas-loader/src/PluginClassLoader.php', - 'Laminas\\Loader\\PluginClassLocator' => $vendorDir . '/laminas/laminas-loader/src/PluginClassLocator.php', - 'Laminas\\Loader\\ShortNameLocator' => $vendorDir . '/laminas/laminas-loader/src/ShortNameLocator.php', - 'Laminas\\Loader\\SplAutoloader' => $vendorDir . '/laminas/laminas-loader/src/SplAutoloader.php', - 'Laminas\\Loader\\StandardAutoloader' => $vendorDir . '/laminas/laminas-loader/src/StandardAutoloader.php', - 'Laminas\\Mail\\Address' => $vendorDir . '/laminas/laminas-mail/src/Address.php', - 'Laminas\\Mail\\AddressList' => $vendorDir . '/laminas/laminas-mail/src/AddressList.php', - 'Laminas\\Mail\\Address\\AddressInterface' => $vendorDir . '/laminas/laminas-mail/src/Address/AddressInterface.php', - 'Laminas\\Mail\\ConfigProvider' => $vendorDir . '/laminas/laminas-mail/src/ConfigProvider.php', - 'Laminas\\Mail\\Exception\\BadMethodCallException' => $vendorDir . '/laminas/laminas-mail/src/Exception/BadMethodCallException.php', - 'Laminas\\Mail\\Exception\\DomainException' => $vendorDir . '/laminas/laminas-mail/src/Exception/DomainException.php', - 'Laminas\\Mail\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mail/src/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-mail/src/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Exception\\OutOfBoundsException' => $vendorDir . '/laminas/laminas-mail/src/Exception/OutOfBoundsException.php', - 'Laminas\\Mail\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mail/src/Exception/RuntimeException.php', - 'Laminas\\Mail\\Header\\AbstractAddressList' => $vendorDir . '/laminas/laminas-mail/src/Header/AbstractAddressList.php', - 'Laminas\\Mail\\Header\\Bcc' => $vendorDir . '/laminas/laminas-mail/src/Header/Bcc.php', - 'Laminas\\Mail\\Header\\Cc' => $vendorDir . '/laminas/laminas-mail/src/Header/Cc.php', - 'Laminas\\Mail\\Header\\ContentDisposition' => $vendorDir . '/laminas/laminas-mail/src/Header/ContentDisposition.php', - 'Laminas\\Mail\\Header\\ContentTransferEncoding' => $vendorDir . '/laminas/laminas-mail/src/Header/ContentTransferEncoding.php', - 'Laminas\\Mail\\Header\\ContentType' => $vendorDir . '/laminas/laminas-mail/src/Header/ContentType.php', - 'Laminas\\Mail\\Header\\Date' => $vendorDir . '/laminas/laminas-mail/src/Header/Date.php', - 'Laminas\\Mail\\Header\\Exception\\BadMethodCallException' => $vendorDir . '/laminas/laminas-mail/src/Header/Exception/BadMethodCallException.php', - 'Laminas\\Mail\\Header\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mail/src/Header/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Header\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-mail/src/Header/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Header\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mail/src/Header/Exception/RuntimeException.php', - 'Laminas\\Mail\\Header\\From' => $vendorDir . '/laminas/laminas-mail/src/Header/From.php', - 'Laminas\\Mail\\Header\\GenericHeader' => $vendorDir . '/laminas/laminas-mail/src/Header/GenericHeader.php', - 'Laminas\\Mail\\Header\\GenericMultiHeader' => $vendorDir . '/laminas/laminas-mail/src/Header/GenericMultiHeader.php', - 'Laminas\\Mail\\Header\\HeaderInterface' => $vendorDir . '/laminas/laminas-mail/src/Header/HeaderInterface.php', - 'Laminas\\Mail\\Header\\HeaderLoader' => $vendorDir . '/laminas/laminas-mail/src/Header/HeaderLoader.php', - 'Laminas\\Mail\\Header\\HeaderLocator' => $vendorDir . '/laminas/laminas-mail/src/Header/HeaderLocator.php', - 'Laminas\\Mail\\Header\\HeaderLocatorInterface' => $vendorDir . '/laminas/laminas-mail/src/Header/HeaderLocatorInterface.php', - 'Laminas\\Mail\\Header\\HeaderName' => $vendorDir . '/laminas/laminas-mail/src/Header/HeaderName.php', - 'Laminas\\Mail\\Header\\HeaderValue' => $vendorDir . '/laminas/laminas-mail/src/Header/HeaderValue.php', - 'Laminas\\Mail\\Header\\HeaderWrap' => $vendorDir . '/laminas/laminas-mail/src/Header/HeaderWrap.php', - 'Laminas\\Mail\\Header\\IdentificationField' => $vendorDir . '/laminas/laminas-mail/src/Header/IdentificationField.php', - 'Laminas\\Mail\\Header\\InReplyTo' => $vendorDir . '/laminas/laminas-mail/src/Header/InReplyTo.php', - 'Laminas\\Mail\\Header\\ListParser' => $vendorDir . '/laminas/laminas-mail/src/Header/ListParser.php', - 'Laminas\\Mail\\Header\\MessageId' => $vendorDir . '/laminas/laminas-mail/src/Header/MessageId.php', - 'Laminas\\Mail\\Header\\MimeVersion' => $vendorDir . '/laminas/laminas-mail/src/Header/MimeVersion.php', - 'Laminas\\Mail\\Header\\MultipleHeadersInterface' => $vendorDir . '/laminas/laminas-mail/src/Header/MultipleHeadersInterface.php', - 'Laminas\\Mail\\Header\\Received' => $vendorDir . '/laminas/laminas-mail/src/Header/Received.php', - 'Laminas\\Mail\\Header\\References' => $vendorDir . '/laminas/laminas-mail/src/Header/References.php', - 'Laminas\\Mail\\Header\\ReplyTo' => $vendorDir . '/laminas/laminas-mail/src/Header/ReplyTo.php', - 'Laminas\\Mail\\Header\\Sender' => $vendorDir . '/laminas/laminas-mail/src/Header/Sender.php', - 'Laminas\\Mail\\Header\\StructuredInterface' => $vendorDir . '/laminas/laminas-mail/src/Header/StructuredInterface.php', - 'Laminas\\Mail\\Header\\Subject' => $vendorDir . '/laminas/laminas-mail/src/Header/Subject.php', - 'Laminas\\Mail\\Header\\To' => $vendorDir . '/laminas/laminas-mail/src/Header/To.php', - 'Laminas\\Mail\\Header\\UnstructuredInterface' => $vendorDir . '/laminas/laminas-mail/src/Header/UnstructuredInterface.php', - 'Laminas\\Mail\\Headers' => $vendorDir . '/laminas/laminas-mail/src/Headers.php', - 'Laminas\\Mail\\Message' => $vendorDir . '/laminas/laminas-mail/src/Message.php', - 'Laminas\\Mail\\MessageFactory' => $vendorDir . '/laminas/laminas-mail/src/MessageFactory.php', - 'Laminas\\Mail\\Module' => $vendorDir . '/laminas/laminas-mail/src/Module.php', - 'Laminas\\Mail\\Protocol\\AbstractProtocol' => $vendorDir . '/laminas/laminas-mail/src/Protocol/AbstractProtocol.php', - 'Laminas\\Mail\\Protocol\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Protocol\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Protocol\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Exception/RuntimeException.php', - 'Laminas\\Mail\\Protocol\\Imap' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Imap.php', - 'Laminas\\Mail\\Protocol\\Pop3' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Pop3.php', - 'Laminas\\Mail\\Protocol\\Pop3\\Response' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Pop3/Response.php', - 'Laminas\\Mail\\Protocol\\Pop3\\Xoauth2\\Microsoft' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Pop3/Xoauth2/Microsoft.php', - 'Laminas\\Mail\\Protocol\\ProtocolTrait' => $vendorDir . '/laminas/laminas-mail/src/Protocol/ProtocolTrait.php', - 'Laminas\\Mail\\Protocol\\Smtp' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp.php', - 'Laminas\\Mail\\Protocol\\SmtpPluginManager' => $vendorDir . '/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php', - 'Laminas\\Mail\\Protocol\\SmtpPluginManagerFactory' => $vendorDir . '/laminas/laminas-mail/src/Protocol/SmtpPluginManagerFactory.php', - 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Crammd5' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php', - 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Login' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php', - 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Plain' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php', - 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Xoauth2' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Xoauth2.php', - 'Laminas\\Mail\\Protocol\\Xoauth2\\Xoauth2' => $vendorDir . '/laminas/laminas-mail/src/Protocol/Xoauth2/Xoauth2.php', - 'Laminas\\Mail\\Storage' => $vendorDir . '/laminas/laminas-mail/src/Storage.php', - 'Laminas\\Mail\\Storage\\AbstractStorage' => $vendorDir . '/laminas/laminas-mail/src/Storage/AbstractStorage.php', - 'Laminas\\Mail\\Storage\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Storage\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-mail/src/Storage/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Storage\\Exception\\OutOfBoundsException' => $vendorDir . '/laminas/laminas-mail/src/Storage/Exception/OutOfBoundsException.php', - 'Laminas\\Mail\\Storage\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mail/src/Storage/Exception/RuntimeException.php', - 'Laminas\\Mail\\Storage\\Folder' => $vendorDir . '/laminas/laminas-mail/src/Storage/Folder.php', - 'Laminas\\Mail\\Storage\\Folder\\FolderInterface' => $vendorDir . '/laminas/laminas-mail/src/Storage/Folder/FolderInterface.php', - 'Laminas\\Mail\\Storage\\Folder\\Maildir' => $vendorDir . '/laminas/laminas-mail/src/Storage/Folder/Maildir.php', - 'Laminas\\Mail\\Storage\\Folder\\Mbox' => $vendorDir . '/laminas/laminas-mail/src/Storage/Folder/Mbox.php', - 'Laminas\\Mail\\Storage\\Imap' => $vendorDir . '/laminas/laminas-mail/src/Storage/Imap.php', - 'Laminas\\Mail\\Storage\\Maildir' => $vendorDir . '/laminas/laminas-mail/src/Storage/Maildir.php', - 'Laminas\\Mail\\Storage\\Mbox' => $vendorDir . '/laminas/laminas-mail/src/Storage/Mbox.php', - 'Laminas\\Mail\\Storage\\Message' => $vendorDir . '/laminas/laminas-mail/src/Storage/Message.php', - 'Laminas\\Mail\\Storage\\Message\\File' => $vendorDir . '/laminas/laminas-mail/src/Storage/Message/File.php', - 'Laminas\\Mail\\Storage\\Message\\MessageInterface' => $vendorDir . '/laminas/laminas-mail/src/Storage/Message/MessageInterface.php', - 'Laminas\\Mail\\Storage\\ParamsNormalizer' => $vendorDir . '/laminas/laminas-mail/src/Storage/ParamsNormalizer.php', - 'Laminas\\Mail\\Storage\\Part' => $vendorDir . '/laminas/laminas-mail/src/Storage/Part.php', - 'Laminas\\Mail\\Storage\\Part\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mail/src/Storage/Part/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Storage\\Part\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-mail/src/Storage/Part/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Storage\\Part\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mail/src/Storage/Part/Exception/RuntimeException.php', - 'Laminas\\Mail\\Storage\\Part\\File' => $vendorDir . '/laminas/laminas-mail/src/Storage/Part/File.php', - 'Laminas\\Mail\\Storage\\Part\\PartInterface' => $vendorDir . '/laminas/laminas-mail/src/Storage/Part/PartInterface.php', - 'Laminas\\Mail\\Storage\\Pop3' => $vendorDir . '/laminas/laminas-mail/src/Storage/Pop3.php', - 'Laminas\\Mail\\Storage\\Writable\\Maildir' => $vendorDir . '/laminas/laminas-mail/src/Storage/Writable/Maildir.php', - 'Laminas\\Mail\\Storage\\Writable\\WritableInterface' => $vendorDir . '/laminas/laminas-mail/src/Storage/Writable/WritableInterface.php', - 'Laminas\\Mail\\Transport\\Envelope' => $vendorDir . '/laminas/laminas-mail/src/Transport/Envelope.php', - 'Laminas\\Mail\\Transport\\Exception\\DomainException' => $vendorDir . '/laminas/laminas-mail/src/Transport/Exception/DomainException.php', - 'Laminas\\Mail\\Transport\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mail/src/Transport/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Transport\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-mail/src/Transport/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Transport\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mail/src/Transport/Exception/RuntimeException.php', - 'Laminas\\Mail\\Transport\\Factory' => $vendorDir . '/laminas/laminas-mail/src/Transport/Factory.php', - 'Laminas\\Mail\\Transport\\File' => $vendorDir . '/laminas/laminas-mail/src/Transport/File.php', - 'Laminas\\Mail\\Transport\\FileOptions' => $vendorDir . '/laminas/laminas-mail/src/Transport/FileOptions.php', - 'Laminas\\Mail\\Transport\\InMemory' => $vendorDir . '/laminas/laminas-mail/src/Transport/InMemory.php', - 'Laminas\\Mail\\Transport\\Sendmail' => $vendorDir . '/laminas/laminas-mail/src/Transport/Sendmail.php', - 'Laminas\\Mail\\Transport\\Smtp' => $vendorDir . '/laminas/laminas-mail/src/Transport/Smtp.php', - 'Laminas\\Mail\\Transport\\SmtpOptions' => $vendorDir . '/laminas/laminas-mail/src/Transport/SmtpOptions.php', - 'Laminas\\Mail\\Transport\\TransportInterface' => $vendorDir . '/laminas/laminas-mail/src/Transport/TransportInterface.php', - 'Laminas\\Mime\\Decode' => $vendorDir . '/laminas/laminas-mime/src/Decode.php', - 'Laminas\\Mime\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-mime/src/Exception/ExceptionInterface.php', - 'Laminas\\Mime\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-mime/src/Exception/InvalidArgumentException.php', - 'Laminas\\Mime\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-mime/src/Exception/RuntimeException.php', - 'Laminas\\Mime\\Message' => $vendorDir . '/laminas/laminas-mime/src/Message.php', - 'Laminas\\Mime\\Mime' => $vendorDir . '/laminas/laminas-mime/src/Mime.php', - 'Laminas\\Mime\\Part' => $vendorDir . '/laminas/laminas-mime/src/Part.php', - 'Laminas\\ServiceManager\\AbstractFactoryInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/AbstractFactoryInterface.php', - 'Laminas\\ServiceManager\\AbstractFactory\\ConfigAbstractFactory' => $vendorDir . '/laminas/laminas-servicemanager/src/AbstractFactory/ConfigAbstractFactory.php', - 'Laminas\\ServiceManager\\AbstractFactory\\ReflectionBasedAbstractFactory' => $vendorDir . '/laminas/laminas-servicemanager/src/AbstractFactory/ReflectionBasedAbstractFactory.php', - 'Laminas\\ServiceManager\\AbstractPluginManager' => $vendorDir . '/laminas/laminas-servicemanager/src/AbstractPluginManager.php', - 'Laminas\\ServiceManager\\Config' => $vendorDir . '/laminas/laminas-servicemanager/src/Config.php', - 'Laminas\\ServiceManager\\ConfigInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/ConfigInterface.php', - 'Laminas\\ServiceManager\\DelegatorFactoryInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/DelegatorFactoryInterface.php', - 'Laminas\\ServiceManager\\Exception\\ContainerModificationsNotAllowedException' => $vendorDir . '/laminas/laminas-servicemanager/src/Exception/ContainerModificationsNotAllowedException.php', - 'Laminas\\ServiceManager\\Exception\\CyclicAliasException' => $vendorDir . '/laminas/laminas-servicemanager/src/Exception/CyclicAliasException.php', - 'Laminas\\ServiceManager\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/Exception/ExceptionInterface.php', - 'Laminas\\ServiceManager\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-servicemanager/src/Exception/InvalidArgumentException.php', - 'Laminas\\ServiceManager\\Exception\\InvalidServiceException' => $vendorDir . '/laminas/laminas-servicemanager/src/Exception/InvalidServiceException.php', - 'Laminas\\ServiceManager\\Exception\\ServiceNotCreatedException' => $vendorDir . '/laminas/laminas-servicemanager/src/Exception/ServiceNotCreatedException.php', - 'Laminas\\ServiceManager\\Exception\\ServiceNotFoundException' => $vendorDir . '/laminas/laminas-servicemanager/src/Exception/ServiceNotFoundException.php', - 'Laminas\\ServiceManager\\FactoryInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/FactoryInterface.php', - 'Laminas\\ServiceManager\\Factory\\AbstractFactoryInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/Factory/AbstractFactoryInterface.php', - 'Laminas\\ServiceManager\\Factory\\DelegatorFactoryInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/Factory/DelegatorFactoryInterface.php', - 'Laminas\\ServiceManager\\Factory\\FactoryInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/Factory/FactoryInterface.php', - 'Laminas\\ServiceManager\\Factory\\InvokableFactory' => $vendorDir . '/laminas/laminas-servicemanager/src/Factory/InvokableFactory.php', - 'Laminas\\ServiceManager\\InitializerInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/InitializerInterface.php', - 'Laminas\\ServiceManager\\Initializer\\InitializerInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/Initializer/InitializerInterface.php', - 'Laminas\\ServiceManager\\PluginManagerInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/PluginManagerInterface.php', - 'Laminas\\ServiceManager\\Proxy\\LazyServiceFactory' => $vendorDir . '/laminas/laminas-servicemanager/src/Proxy/LazyServiceFactory.php', - 'Laminas\\ServiceManager\\ServiceLocatorInterface' => $vendorDir . '/laminas/laminas-servicemanager/src/ServiceLocatorInterface.php', - 'Laminas\\ServiceManager\\ServiceManager' => $vendorDir . '/laminas/laminas-servicemanager/src/ServiceManager.php', - 'Laminas\\ServiceManager\\Tool\\ConfigDumper' => $vendorDir . '/laminas/laminas-servicemanager/src/Tool/ConfigDumper.php', - 'Laminas\\ServiceManager\\Tool\\ConfigDumperCommand' => $vendorDir . '/laminas/laminas-servicemanager/src/Tool/ConfigDumperCommand.php', - 'Laminas\\ServiceManager\\Tool\\FactoryCreator' => $vendorDir . '/laminas/laminas-servicemanager/src/Tool/FactoryCreator.php', - 'Laminas\\ServiceManager\\Tool\\FactoryCreatorCommand' => $vendorDir . '/laminas/laminas-servicemanager/src/Tool/FactoryCreatorCommand.php', - 'Laminas\\Stdlib\\AbstractOptions' => $vendorDir . '/laminas/laminas-stdlib/src/AbstractOptions.php', - 'Laminas\\Stdlib\\ArrayObject' => $vendorDir . '/laminas/laminas-stdlib/src/ArrayObject.php', - 'Laminas\\Stdlib\\ArraySerializableInterface' => $vendorDir . '/laminas/laminas-stdlib/src/ArraySerializableInterface.php', - 'Laminas\\Stdlib\\ArrayStack' => $vendorDir . '/laminas/laminas-stdlib/src/ArrayStack.php', - 'Laminas\\Stdlib\\ArrayUtils' => $vendorDir . '/laminas/laminas-stdlib/src/ArrayUtils.php', - 'Laminas\\Stdlib\\ArrayUtils\\MergeRemoveKey' => $vendorDir . '/laminas/laminas-stdlib/src/ArrayUtils/MergeRemoveKey.php', - 'Laminas\\Stdlib\\ArrayUtils\\MergeReplaceKey' => $vendorDir . '/laminas/laminas-stdlib/src/ArrayUtils/MergeReplaceKey.php', - 'Laminas\\Stdlib\\ArrayUtils\\MergeReplaceKeyInterface' => $vendorDir . '/laminas/laminas-stdlib/src/ArrayUtils/MergeReplaceKeyInterface.php', - 'Laminas\\Stdlib\\ConsoleHelper' => $vendorDir . '/laminas/laminas-stdlib/src/ConsoleHelper.php', - 'Laminas\\Stdlib\\DispatchableInterface' => $vendorDir . '/laminas/laminas-stdlib/src/DispatchableInterface.php', - 'Laminas\\Stdlib\\ErrorHandler' => $vendorDir . '/laminas/laminas-stdlib/src/ErrorHandler.php', - 'Laminas\\Stdlib\\Exception\\BadMethodCallException' => $vendorDir . '/laminas/laminas-stdlib/src/Exception/BadMethodCallException.php', - 'Laminas\\Stdlib\\Exception\\DomainException' => $vendorDir . '/laminas/laminas-stdlib/src/Exception/DomainException.php', - 'Laminas\\Stdlib\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-stdlib/src/Exception/ExceptionInterface.php', - 'Laminas\\Stdlib\\Exception\\ExtensionNotLoadedException' => $vendorDir . '/laminas/laminas-stdlib/src/Exception/ExtensionNotLoadedException.php', - 'Laminas\\Stdlib\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-stdlib/src/Exception/InvalidArgumentException.php', - 'Laminas\\Stdlib\\Exception\\LogicException' => $vendorDir . '/laminas/laminas-stdlib/src/Exception/LogicException.php', - 'Laminas\\Stdlib\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-stdlib/src/Exception/RuntimeException.php', - 'Laminas\\Stdlib\\FastPriorityQueue' => $vendorDir . '/laminas/laminas-stdlib/src/FastPriorityQueue.php', - 'Laminas\\Stdlib\\Glob' => $vendorDir . '/laminas/laminas-stdlib/src/Glob.php', - 'Laminas\\Stdlib\\Guard\\AllGuardsTrait' => $vendorDir . '/laminas/laminas-stdlib/src/Guard/AllGuardsTrait.php', - 'Laminas\\Stdlib\\Guard\\ArrayOrTraversableGuardTrait' => $vendorDir . '/laminas/laminas-stdlib/src/Guard/ArrayOrTraversableGuardTrait.php', - 'Laminas\\Stdlib\\Guard\\EmptyGuardTrait' => $vendorDir . '/laminas/laminas-stdlib/src/Guard/EmptyGuardTrait.php', - 'Laminas\\Stdlib\\Guard\\NullGuardTrait' => $vendorDir . '/laminas/laminas-stdlib/src/Guard/NullGuardTrait.php', - 'Laminas\\Stdlib\\InitializableInterface' => $vendorDir . '/laminas/laminas-stdlib/src/InitializableInterface.php', - 'Laminas\\Stdlib\\JsonSerializable' => $vendorDir . '/laminas/laminas-stdlib/src/JsonSerializable.php', - 'Laminas\\Stdlib\\Message' => $vendorDir . '/laminas/laminas-stdlib/src/Message.php', - 'Laminas\\Stdlib\\MessageInterface' => $vendorDir . '/laminas/laminas-stdlib/src/MessageInterface.php', - 'Laminas\\Stdlib\\ParameterObjectInterface' => $vendorDir . '/laminas/laminas-stdlib/src/ParameterObjectInterface.php', - 'Laminas\\Stdlib\\Parameters' => $vendorDir . '/laminas/laminas-stdlib/src/Parameters.php', - 'Laminas\\Stdlib\\ParametersInterface' => $vendorDir . '/laminas/laminas-stdlib/src/ParametersInterface.php', - 'Laminas\\Stdlib\\PriorityList' => $vendorDir . '/laminas/laminas-stdlib/src/PriorityList.php', - 'Laminas\\Stdlib\\PriorityQueue' => $vendorDir . '/laminas/laminas-stdlib/src/PriorityQueue.php', - 'Laminas\\Stdlib\\Request' => $vendorDir . '/laminas/laminas-stdlib/src/Request.php', - 'Laminas\\Stdlib\\RequestInterface' => $vendorDir . '/laminas/laminas-stdlib/src/RequestInterface.php', - 'Laminas\\Stdlib\\Response' => $vendorDir . '/laminas/laminas-stdlib/src/Response.php', - 'Laminas\\Stdlib\\ResponseInterface' => $vendorDir . '/laminas/laminas-stdlib/src/ResponseInterface.php', - 'Laminas\\Stdlib\\SplPriorityQueue' => $vendorDir . '/laminas/laminas-stdlib/src/SplPriorityQueue.php', - 'Laminas\\Stdlib\\SplQueue' => $vendorDir . '/laminas/laminas-stdlib/src/SplQueue.php', - 'Laminas\\Stdlib\\SplStack' => $vendorDir . '/laminas/laminas-stdlib/src/SplStack.php', - 'Laminas\\Stdlib\\StringUtils' => $vendorDir . '/laminas/laminas-stdlib/src/StringUtils.php', - 'Laminas\\Stdlib\\StringWrapper\\AbstractStringWrapper' => $vendorDir . '/laminas/laminas-stdlib/src/StringWrapper/AbstractStringWrapper.php', - 'Laminas\\Stdlib\\StringWrapper\\Iconv' => $vendorDir . '/laminas/laminas-stdlib/src/StringWrapper/Iconv.php', - 'Laminas\\Stdlib\\StringWrapper\\Intl' => $vendorDir . '/laminas/laminas-stdlib/src/StringWrapper/Intl.php', - 'Laminas\\Stdlib\\StringWrapper\\MbString' => $vendorDir . '/laminas/laminas-stdlib/src/StringWrapper/MbString.php', - 'Laminas\\Stdlib\\StringWrapper\\Native' => $vendorDir . '/laminas/laminas-stdlib/src/StringWrapper/Native.php', - 'Laminas\\Stdlib\\StringWrapper\\StringWrapperInterface' => $vendorDir . '/laminas/laminas-stdlib/src/StringWrapper/StringWrapperInterface.php', - 'Laminas\\Validator\\AbstractValidator' => $vendorDir . '/laminas/laminas-validator/src/AbstractValidator.php', - 'Laminas\\Validator\\Barcode' => $vendorDir . '/laminas/laminas-validator/src/Barcode.php', - 'Laminas\\Validator\\Barcode\\AbstractAdapter' => $vendorDir . '/laminas/laminas-validator/src/Barcode/AbstractAdapter.php', - 'Laminas\\Validator\\Barcode\\AdapterInterface' => $vendorDir . '/laminas/laminas-validator/src/Barcode/AdapterInterface.php', - 'Laminas\\Validator\\Barcode\\Codabar' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Codabar.php', - 'Laminas\\Validator\\Barcode\\Code128' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Code128.php', - 'Laminas\\Validator\\Barcode\\Code25' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Code25.php', - 'Laminas\\Validator\\Barcode\\Code25interleaved' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Code25interleaved.php', - 'Laminas\\Validator\\Barcode\\Code39' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Code39.php', - 'Laminas\\Validator\\Barcode\\Code39ext' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Code39ext.php', - 'Laminas\\Validator\\Barcode\\Code93' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Code93.php', - 'Laminas\\Validator\\Barcode\\Code93ext' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Code93ext.php', - 'Laminas\\Validator\\Barcode\\Ean12' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Ean12.php', - 'Laminas\\Validator\\Barcode\\Ean13' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Ean13.php', - 'Laminas\\Validator\\Barcode\\Ean14' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Ean14.php', - 'Laminas\\Validator\\Barcode\\Ean18' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Ean18.php', - 'Laminas\\Validator\\Barcode\\Ean2' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Ean2.php', - 'Laminas\\Validator\\Barcode\\Ean5' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Ean5.php', - 'Laminas\\Validator\\Barcode\\Ean8' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Ean8.php', - 'Laminas\\Validator\\Barcode\\Gtin12' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Gtin12.php', - 'Laminas\\Validator\\Barcode\\Gtin13' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Gtin13.php', - 'Laminas\\Validator\\Barcode\\Gtin14' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Gtin14.php', - 'Laminas\\Validator\\Barcode\\Identcode' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Identcode.php', - 'Laminas\\Validator\\Barcode\\Intelligentmail' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Intelligentmail.php', - 'Laminas\\Validator\\Barcode\\Issn' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Issn.php', - 'Laminas\\Validator\\Barcode\\Itf14' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Itf14.php', - 'Laminas\\Validator\\Barcode\\Leitcode' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Leitcode.php', - 'Laminas\\Validator\\Barcode\\Planet' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Planet.php', - 'Laminas\\Validator\\Barcode\\Postnet' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Postnet.php', - 'Laminas\\Validator\\Barcode\\Royalmail' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Royalmail.php', - 'Laminas\\Validator\\Barcode\\Sscc' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Sscc.php', - 'Laminas\\Validator\\Barcode\\Upca' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Upca.php', - 'Laminas\\Validator\\Barcode\\Upce' => $vendorDir . '/laminas/laminas-validator/src/Barcode/Upce.php', - 'Laminas\\Validator\\Between' => $vendorDir . '/laminas/laminas-validator/src/Between.php', - 'Laminas\\Validator\\Bitwise' => $vendorDir . '/laminas/laminas-validator/src/Bitwise.php', - 'Laminas\\Validator\\BusinessIdentifierCode' => $vendorDir . '/laminas/laminas-validator/src/BusinessIdentifierCode.php', - 'Laminas\\Validator\\Callback' => $vendorDir . '/laminas/laminas-validator/src/Callback.php', - 'Laminas\\Validator\\ConfigProvider' => $vendorDir . '/laminas/laminas-validator/src/ConfigProvider.php', - 'Laminas\\Validator\\CreditCard' => $vendorDir . '/laminas/laminas-validator/src/CreditCard.php', - 'Laminas\\Validator\\Csrf' => $vendorDir . '/laminas/laminas-validator/src/Csrf.php', - 'Laminas\\Validator\\Date' => $vendorDir . '/laminas/laminas-validator/src/Date.php', - 'Laminas\\Validator\\DateStep' => $vendorDir . '/laminas/laminas-validator/src/DateStep.php', - 'Laminas\\Validator\\Db\\AbstractDb' => $vendorDir . '/laminas/laminas-validator/src/Db/AbstractDb.php', - 'Laminas\\Validator\\Db\\NoRecordExists' => $vendorDir . '/laminas/laminas-validator/src/Db/NoRecordExists.php', - 'Laminas\\Validator\\Db\\RecordExists' => $vendorDir . '/laminas/laminas-validator/src/Db/RecordExists.php', - 'Laminas\\Validator\\Digits' => $vendorDir . '/laminas/laminas-validator/src/Digits.php', - 'Laminas\\Validator\\EmailAddress' => $vendorDir . '/laminas/laminas-validator/src/EmailAddress.php', - 'Laminas\\Validator\\Exception\\BadMethodCallException' => $vendorDir . '/laminas/laminas-validator/src/Exception/BadMethodCallException.php', - 'Laminas\\Validator\\Exception\\ExceptionInterface' => $vendorDir . '/laminas/laminas-validator/src/Exception/ExceptionInterface.php', - 'Laminas\\Validator\\Exception\\ExtensionNotLoadedException' => $vendorDir . '/laminas/laminas-validator/src/Exception/ExtensionNotLoadedException.php', - 'Laminas\\Validator\\Exception\\InvalidArgumentException' => $vendorDir . '/laminas/laminas-validator/src/Exception/InvalidArgumentException.php', - 'Laminas\\Validator\\Exception\\InvalidMagicMimeFileException' => $vendorDir . '/laminas/laminas-validator/src/Exception/InvalidMagicMimeFileException.php', - 'Laminas\\Validator\\Exception\\RuntimeException' => $vendorDir . '/laminas/laminas-validator/src/Exception/RuntimeException.php', - 'Laminas\\Validator\\Explode' => $vendorDir . '/laminas/laminas-validator/src/Explode.php', - 'Laminas\\Validator\\File\\Count' => $vendorDir . '/laminas/laminas-validator/src/File/Count.php', - 'Laminas\\Validator\\File\\Crc32' => $vendorDir . '/laminas/laminas-validator/src/File/Crc32.php', - 'Laminas\\Validator\\File\\ExcludeExtension' => $vendorDir . '/laminas/laminas-validator/src/File/ExcludeExtension.php', - 'Laminas\\Validator\\File\\ExcludeMimeType' => $vendorDir . '/laminas/laminas-validator/src/File/ExcludeMimeType.php', - 'Laminas\\Validator\\File\\Exists' => $vendorDir . '/laminas/laminas-validator/src/File/Exists.php', - 'Laminas\\Validator\\File\\Extension' => $vendorDir . '/laminas/laminas-validator/src/File/Extension.php', - 'Laminas\\Validator\\File\\FileInformationTrait' => $vendorDir . '/laminas/laminas-validator/src/File/FileInformationTrait.php', - 'Laminas\\Validator\\File\\FilesSize' => $vendorDir . '/laminas/laminas-validator/src/File/FilesSize.php', - 'Laminas\\Validator\\File\\Hash' => $vendorDir . '/laminas/laminas-validator/src/File/Hash.php', - 'Laminas\\Validator\\File\\ImageSize' => $vendorDir . '/laminas/laminas-validator/src/File/ImageSize.php', - 'Laminas\\Validator\\File\\IsCompressed' => $vendorDir . '/laminas/laminas-validator/src/File/IsCompressed.php', - 'Laminas\\Validator\\File\\IsImage' => $vendorDir . '/laminas/laminas-validator/src/File/IsImage.php', - 'Laminas\\Validator\\File\\Md5' => $vendorDir . '/laminas/laminas-validator/src/File/Md5.php', - 'Laminas\\Validator\\File\\MimeType' => $vendorDir . '/laminas/laminas-validator/src/File/MimeType.php', - 'Laminas\\Validator\\File\\NotExists' => $vendorDir . '/laminas/laminas-validator/src/File/NotExists.php', - 'Laminas\\Validator\\File\\Sha1' => $vendorDir . '/laminas/laminas-validator/src/File/Sha1.php', - 'Laminas\\Validator\\File\\Size' => $vendorDir . '/laminas/laminas-validator/src/File/Size.php', - 'Laminas\\Validator\\File\\Upload' => $vendorDir . '/laminas/laminas-validator/src/File/Upload.php', - 'Laminas\\Validator\\File\\UploadFile' => $vendorDir . '/laminas/laminas-validator/src/File/UploadFile.php', - 'Laminas\\Validator\\File\\WordCount' => $vendorDir . '/laminas/laminas-validator/src/File/WordCount.php', - 'Laminas\\Validator\\GpsPoint' => $vendorDir . '/laminas/laminas-validator/src/GpsPoint.php', - 'Laminas\\Validator\\GreaterThan' => $vendorDir . '/laminas/laminas-validator/src/GreaterThan.php', - 'Laminas\\Validator\\Hex' => $vendorDir . '/laminas/laminas-validator/src/Hex.php', - 'Laminas\\Validator\\Hostname' => $vendorDir . '/laminas/laminas-validator/src/Hostname.php', - 'Laminas\\Validator\\Iban' => $vendorDir . '/laminas/laminas-validator/src/Iban.php', - 'Laminas\\Validator\\Identical' => $vendorDir . '/laminas/laminas-validator/src/Identical.php', - 'Laminas\\Validator\\InArray' => $vendorDir . '/laminas/laminas-validator/src/InArray.php', - 'Laminas\\Validator\\Ip' => $vendorDir . '/laminas/laminas-validator/src/Ip.php', - 'Laminas\\Validator\\IsCountable' => $vendorDir . '/laminas/laminas-validator/src/IsCountable.php', - 'Laminas\\Validator\\IsInstanceOf' => $vendorDir . '/laminas/laminas-validator/src/IsInstanceOf.php', - 'Laminas\\Validator\\Isbn' => $vendorDir . '/laminas/laminas-validator/src/Isbn.php', - 'Laminas\\Validator\\Isbn\\Isbn10' => $vendorDir . '/laminas/laminas-validator/src/Isbn/Isbn10.php', - 'Laminas\\Validator\\Isbn\\Isbn13' => $vendorDir . '/laminas/laminas-validator/src/Isbn/Isbn13.php', - 'Laminas\\Validator\\LessThan' => $vendorDir . '/laminas/laminas-validator/src/LessThan.php', - 'Laminas\\Validator\\Module' => $vendorDir . '/laminas/laminas-validator/src/Module.php', - 'Laminas\\Validator\\NotEmpty' => $vendorDir . '/laminas/laminas-validator/src/NotEmpty.php', - 'Laminas\\Validator\\Regex' => $vendorDir . '/laminas/laminas-validator/src/Regex.php', - 'Laminas\\Validator\\Sitemap\\Changefreq' => $vendorDir . '/laminas/laminas-validator/src/Sitemap/Changefreq.php', - 'Laminas\\Validator\\Sitemap\\Lastmod' => $vendorDir . '/laminas/laminas-validator/src/Sitemap/Lastmod.php', - 'Laminas\\Validator\\Sitemap\\Loc' => $vendorDir . '/laminas/laminas-validator/src/Sitemap/Loc.php', - 'Laminas\\Validator\\Sitemap\\Priority' => $vendorDir . '/laminas/laminas-validator/src/Sitemap/Priority.php', - 'Laminas\\Validator\\StaticValidator' => $vendorDir . '/laminas/laminas-validator/src/StaticValidator.php', - 'Laminas\\Validator\\Step' => $vendorDir . '/laminas/laminas-validator/src/Step.php', - 'Laminas\\Validator\\StringLength' => $vendorDir . '/laminas/laminas-validator/src/StringLength.php', - 'Laminas\\Validator\\Timezone' => $vendorDir . '/laminas/laminas-validator/src/Timezone.php', - 'Laminas\\Validator\\Translator\\TranslatorAwareInterface' => $vendorDir . '/laminas/laminas-validator/src/Translator/TranslatorAwareInterface.php', - 'Laminas\\Validator\\Translator\\TranslatorInterface' => $vendorDir . '/laminas/laminas-validator/src/Translator/TranslatorInterface.php', - 'Laminas\\Validator\\UndisclosedPassword' => $vendorDir . '/laminas/laminas-validator/src/UndisclosedPassword.php', - 'Laminas\\Validator\\Uri' => $vendorDir . '/laminas/laminas-validator/src/Uri.php', - 'Laminas\\Validator\\Uuid' => $vendorDir . '/laminas/laminas-validator/src/Uuid.php', - 'Laminas\\Validator\\ValidatorChain' => $vendorDir . '/laminas/laminas-validator/src/ValidatorChain.php', - 'Laminas\\Validator\\ValidatorInterface' => $vendorDir . '/laminas/laminas-validator/src/ValidatorInterface.php', - 'Laminas\\Validator\\ValidatorPluginManager' => $vendorDir . '/laminas/laminas-validator/src/ValidatorPluginManager.php', - 'Laminas\\Validator\\ValidatorPluginManagerAwareInterface' => $vendorDir . '/laminas/laminas-validator/src/ValidatorPluginManagerAwareInterface.php', - 'Laminas\\Validator\\ValidatorPluginManagerFactory' => $vendorDir . '/laminas/laminas-validator/src/ValidatorPluginManagerFactory.php', - 'Laminas\\Validator\\ValidatorProviderInterface' => $vendorDir . '/laminas/laminas-validator/src/ValidatorProviderInterface.php', 'League\\OAuth2\\Client\\Exception\\HostedDomainException' => $vendorDir . '/league/oauth2-google/src/Exception/HostedDomainException.php', 'League\\OAuth2\\Client\\Grant\\AbstractGrant' => $vendorDir . '/league/oauth2-client/src/Grant/AbstractGrant.php', 'League\\OAuth2\\Client\\Grant\\AuthorizationCode' => $vendorDir . '/league/oauth2-client/src/Grant/AuthorizationCode.php', @@ -1100,6 +875,7 @@ return array( 'League\\OAuth2\\Client\\Token\\AccessToken' => $vendorDir . '/league/oauth2-client/src/Token/AccessToken.php', 'League\\OAuth2\\Client\\Token\\AccessTokenInterface' => $vendorDir . '/league/oauth2-client/src/Token/AccessTokenInterface.php', 'League\\OAuth2\\Client\\Token\\ResourceOwnerAccessTokenInterface' => $vendorDir . '/league/oauth2-client/src/Token/ResourceOwnerAccessTokenInterface.php', + 'League\\OAuth2\\Client\\Token\\SettableRefreshTokenInterface' => $vendorDir . '/league/oauth2-client/src/Token/SettableRefreshTokenInterface.php', 'League\\OAuth2\\Client\\Tool\\ArrayAccessorTrait' => $vendorDir . '/league/oauth2-client/src/Tool/ArrayAccessorTrait.php', 'League\\OAuth2\\Client\\Tool\\BearerAuthorizationTrait' => $vendorDir . '/league/oauth2-client/src/Tool/BearerAuthorizationTrait.php', 'League\\OAuth2\\Client\\Tool\\GuardedPropertyTrait' => $vendorDir . '/league/oauth2-client/src/Tool/GuardedPropertyTrait.php', @@ -1188,10 +964,13 @@ return array( 'Pelago\\Emogrifier\\Css\\StyleRule' => $vendorDir . '/pelago/emogrifier/src/Css/StyleRule.php', 'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/AbstractHtmlProcessor.php', 'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/CssToAttributeConverter.php', + 'Pelago\\Emogrifier\\HtmlProcessor\\CssVariableEvaluator' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/CssVariableEvaluator.php', 'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/HtmlNormalizer.php', 'Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner' => $vendorDir . '/pelago/emogrifier/src/HtmlProcessor/HtmlPruner.php', 'Pelago\\Emogrifier\\Utilities\\ArrayIntersector' => $vendorDir . '/pelago/emogrifier/src/Utilities/ArrayIntersector.php', 'Pelago\\Emogrifier\\Utilities\\CssConcatenator' => $vendorDir . '/pelago/emogrifier/src/Utilities/CssConcatenator.php', + 'Pelago\\Emogrifier\\Utilities\\DeclarationBlockParser' => $vendorDir . '/pelago/emogrifier/src/Utilities/DeclarationBlockParser.php', + 'Pelago\\Emogrifier\\Utilities\\Preg' => $vendorDir . '/pelago/emogrifier/src/Utilities/Preg.php', 'PhpParser\\Builder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder.php', 'PhpParser\\BuilderFactory' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php', 'PhpParser\\BuilderHelpers' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php', @@ -1521,6 +1300,7 @@ return array( 'SQLUnionQuery' => $baseDir . '/core/sqlunionquery.class.inc.php', 'SQLite3Exception' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php', 'SVGDOMSanitizer' => $baseDir . '/core/htmlsanitizer.class.inc.php', + 'Sabberworm\\CSS\\CSSElement' => $vendorDir . '/sabberworm/php-css-parser/src/CSSElement.php', 'Sabberworm\\CSS\\CSSList\\AtRuleBlockList' => $vendorDir . '/sabberworm/php-css-parser/src/CSSList/AtRuleBlockList.php', 'Sabberworm\\CSS\\CSSList\\CSSBlockList' => $vendorDir . '/sabberworm/php-css-parser/src/CSSList/CSSBlockList.php', 'Sabberworm\\CSS\\CSSList\\CSSList' => $vendorDir . '/sabberworm/php-css-parser/src/CSSList/CSSList.php', @@ -1531,11 +1311,14 @@ return array( 'Sabberworm\\CSS\\OutputFormat' => $vendorDir . '/sabberworm/php-css-parser/src/OutputFormat.php', 'Sabberworm\\CSS\\OutputFormatter' => $vendorDir . '/sabberworm/php-css-parser/src/OutputFormatter.php', 'Sabberworm\\CSS\\Parser' => $vendorDir . '/sabberworm/php-css-parser/src/Parser.php', + 'Sabberworm\\CSS\\Parsing\\Anchor' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/Anchor.php', 'Sabberworm\\CSS\\Parsing\\OutputException' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/OutputException.php', 'Sabberworm\\CSS\\Parsing\\ParserState' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/ParserState.php', 'Sabberworm\\CSS\\Parsing\\SourceException' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/SourceException.php', 'Sabberworm\\CSS\\Parsing\\UnexpectedEOFException' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/UnexpectedEOFException.php', 'Sabberworm\\CSS\\Parsing\\UnexpectedTokenException' => $vendorDir . '/sabberworm/php-css-parser/src/Parsing/UnexpectedTokenException.php', + 'Sabberworm\\CSS\\Position\\Position' => $vendorDir . '/sabberworm/php-css-parser/src/Position/Position.php', + 'Sabberworm\\CSS\\Position\\Positionable' => $vendorDir . '/sabberworm/php-css-parser/src/Position/Positionable.php', 'Sabberworm\\CSS\\Property\\AtRule' => $vendorDir . '/sabberworm/php-css-parser/src/Property/AtRule.php', 'Sabberworm\\CSS\\Property\\CSSNamespace' => $vendorDir . '/sabberworm/php-css-parser/src/Property/CSSNamespace.php', 'Sabberworm\\CSS\\Property\\Charset' => $vendorDir . '/sabberworm/php-css-parser/src/Property/Charset.php', @@ -2661,6 +2444,128 @@ return array( 'Symfony\\Component\\HttpKernel\\RebootableInterface' => $vendorDir . '/symfony/http-kernel/RebootableInterface.php', 'Symfony\\Component\\HttpKernel\\TerminableInterface' => $vendorDir . '/symfony/http-kernel/TerminableInterface.php', 'Symfony\\Component\\HttpKernel\\UriSigner' => $vendorDir . '/symfony/http-kernel/UriSigner.php', + 'Symfony\\Component\\Mailer\\Command\\MailerTestCommand' => $vendorDir . '/symfony/mailer/Command/MailerTestCommand.php', + 'Symfony\\Component\\Mailer\\DataCollector\\MessageDataCollector' => $vendorDir . '/symfony/mailer/DataCollector/MessageDataCollector.php', + 'Symfony\\Component\\Mailer\\DelayedEnvelope' => $vendorDir . '/symfony/mailer/DelayedEnvelope.php', + 'Symfony\\Component\\Mailer\\Envelope' => $vendorDir . '/symfony/mailer/Envelope.php', + 'Symfony\\Component\\Mailer\\EventListener\\EnvelopeListener' => $vendorDir . '/symfony/mailer/EventListener/EnvelopeListener.php', + 'Symfony\\Component\\Mailer\\EventListener\\MessageListener' => $vendorDir . '/symfony/mailer/EventListener/MessageListener.php', + 'Symfony\\Component\\Mailer\\EventListener\\MessageLoggerListener' => $vendorDir . '/symfony/mailer/EventListener/MessageLoggerListener.php', + 'Symfony\\Component\\Mailer\\EventListener\\MessengerTransportListener' => $vendorDir . '/symfony/mailer/EventListener/MessengerTransportListener.php', + 'Symfony\\Component\\Mailer\\Event\\FailedMessageEvent' => $vendorDir . '/symfony/mailer/Event/FailedMessageEvent.php', + 'Symfony\\Component\\Mailer\\Event\\MessageEvent' => $vendorDir . '/symfony/mailer/Event/MessageEvent.php', + 'Symfony\\Component\\Mailer\\Event\\MessageEvents' => $vendorDir . '/symfony/mailer/Event/MessageEvents.php', + 'Symfony\\Component\\Mailer\\Event\\SentMessageEvent' => $vendorDir . '/symfony/mailer/Event/SentMessageEvent.php', + 'Symfony\\Component\\Mailer\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/mailer/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Mailer\\Exception\\HttpTransportException' => $vendorDir . '/symfony/mailer/Exception/HttpTransportException.php', + 'Symfony\\Component\\Mailer\\Exception\\IncompleteDsnException' => $vendorDir . '/symfony/mailer/Exception/IncompleteDsnException.php', + 'Symfony\\Component\\Mailer\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/mailer/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Mailer\\Exception\\LogicException' => $vendorDir . '/symfony/mailer/Exception/LogicException.php', + 'Symfony\\Component\\Mailer\\Exception\\RuntimeException' => $vendorDir . '/symfony/mailer/Exception/RuntimeException.php', + 'Symfony\\Component\\Mailer\\Exception\\TransportException' => $vendorDir . '/symfony/mailer/Exception/TransportException.php', + 'Symfony\\Component\\Mailer\\Exception\\TransportExceptionInterface' => $vendorDir . '/symfony/mailer/Exception/TransportExceptionInterface.php', + 'Symfony\\Component\\Mailer\\Exception\\UnexpectedResponseException' => $vendorDir . '/symfony/mailer/Exception/UnexpectedResponseException.php', + 'Symfony\\Component\\Mailer\\Exception\\UnsupportedSchemeException' => $vendorDir . '/symfony/mailer/Exception/UnsupportedSchemeException.php', + 'Symfony\\Component\\Mailer\\Header\\MetadataHeader' => $vendorDir . '/symfony/mailer/Header/MetadataHeader.php', + 'Symfony\\Component\\Mailer\\Header\\TagHeader' => $vendorDir . '/symfony/mailer/Header/TagHeader.php', + 'Symfony\\Component\\Mailer\\Mailer' => $vendorDir . '/symfony/mailer/Mailer.php', + 'Symfony\\Component\\Mailer\\MailerInterface' => $vendorDir . '/symfony/mailer/MailerInterface.php', + 'Symfony\\Component\\Mailer\\Messenger\\MessageHandler' => $vendorDir . '/symfony/mailer/Messenger/MessageHandler.php', + 'Symfony\\Component\\Mailer\\Messenger\\SendEmailMessage' => $vendorDir . '/symfony/mailer/Messenger/SendEmailMessage.php', + 'Symfony\\Component\\Mailer\\SentMessage' => $vendorDir . '/symfony/mailer/SentMessage.php', + 'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailCount' => $vendorDir . '/symfony/mailer/Test/Constraint/EmailCount.php', + 'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailIsQueued' => $vendorDir . '/symfony/mailer/Test/Constraint/EmailIsQueued.php', + 'Symfony\\Component\\Mailer\\Test\\TransportFactoryTestCase' => $vendorDir . '/symfony/mailer/Test/TransportFactoryTestCase.php', + 'Symfony\\Component\\Mailer\\Transport' => $vendorDir . '/symfony/mailer/Transport.php', + 'Symfony\\Component\\Mailer\\Transport\\AbstractApiTransport' => $vendorDir . '/symfony/mailer/Transport/AbstractApiTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\AbstractHttpTransport' => $vendorDir . '/symfony/mailer/Transport/AbstractHttpTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\AbstractTransport' => $vendorDir . '/symfony/mailer/Transport/AbstractTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\AbstractTransportFactory' => $vendorDir . '/symfony/mailer/Transport/AbstractTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\Dsn' => $vendorDir . '/symfony/mailer/Transport/Dsn.php', + 'Symfony\\Component\\Mailer\\Transport\\FailoverTransport' => $vendorDir . '/symfony/mailer/Transport/FailoverTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\NativeTransportFactory' => $vendorDir . '/symfony/mailer/Transport/NativeTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\NullTransport' => $vendorDir . '/symfony/mailer/Transport/NullTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\NullTransportFactory' => $vendorDir . '/symfony/mailer/Transport/NullTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\RoundRobinTransport' => $vendorDir . '/symfony/mailer/Transport/RoundRobinTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\SendmailTransport' => $vendorDir . '/symfony/mailer/Transport/SendmailTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\SendmailTransportFactory' => $vendorDir . '/symfony/mailer/Transport/SendmailTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\AuthenticatorInterface' => $vendorDir . '/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\CramMd5Authenticator' => $vendorDir . '/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\LoginAuthenticator' => $vendorDir . '/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\PlainAuthenticator' => $vendorDir . '/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\XOAuth2Authenticator' => $vendorDir . '/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransport' => $vendorDir . '/symfony/mailer/Transport/Smtp/EsmtpTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransportFactory' => $vendorDir . '/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\SmtpTransport' => $vendorDir . '/symfony/mailer/Transport/Smtp/SmtpTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Stream\\AbstractStream' => $vendorDir . '/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Stream\\ProcessStream' => $vendorDir . '/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Stream\\SocketStream' => $vendorDir . '/symfony/mailer/Transport/Smtp/Stream/SocketStream.php', + 'Symfony\\Component\\Mailer\\Transport\\TransportFactoryInterface' => $vendorDir . '/symfony/mailer/Transport/TransportFactoryInterface.php', + 'Symfony\\Component\\Mailer\\Transport\\TransportInterface' => $vendorDir . '/symfony/mailer/Transport/TransportInterface.php', + 'Symfony\\Component\\Mailer\\Transport\\Transports' => $vendorDir . '/symfony/mailer/Transport/Transports.php', + 'Symfony\\Component\\Mime\\Address' => $vendorDir . '/symfony/mime/Address.php', + 'Symfony\\Component\\Mime\\BodyRendererInterface' => $vendorDir . '/symfony/mime/BodyRendererInterface.php', + 'Symfony\\Component\\Mime\\CharacterStream' => $vendorDir . '/symfony/mime/CharacterStream.php', + 'Symfony\\Component\\Mime\\Crypto\\DkimOptions' => $vendorDir . '/symfony/mime/Crypto/DkimOptions.php', + 'Symfony\\Component\\Mime\\Crypto\\DkimSigner' => $vendorDir . '/symfony/mime/Crypto/DkimSigner.php', + 'Symfony\\Component\\Mime\\Crypto\\SMime' => $vendorDir . '/symfony/mime/Crypto/SMime.php', + 'Symfony\\Component\\Mime\\Crypto\\SMimeEncrypter' => $vendorDir . '/symfony/mime/Crypto/SMimeEncrypter.php', + 'Symfony\\Component\\Mime\\Crypto\\SMimeSigner' => $vendorDir . '/symfony/mime/Crypto/SMimeSigner.php', + 'Symfony\\Component\\Mime\\DependencyInjection\\AddMimeTypeGuesserPass' => $vendorDir . '/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php', + 'Symfony\\Component\\Mime\\DraftEmail' => $vendorDir . '/symfony/mime/DraftEmail.php', + 'Symfony\\Component\\Mime\\Email' => $vendorDir . '/symfony/mime/Email.php', + 'Symfony\\Component\\Mime\\Encoder\\AddressEncoderInterface' => $vendorDir . '/symfony/mime/Encoder/AddressEncoderInterface.php', + 'Symfony\\Component\\Mime\\Encoder\\Base64ContentEncoder' => $vendorDir . '/symfony/mime/Encoder/Base64ContentEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\Base64Encoder' => $vendorDir . '/symfony/mime/Encoder/Base64Encoder.php', + 'Symfony\\Component\\Mime\\Encoder\\Base64MimeHeaderEncoder' => $vendorDir . '/symfony/mime/Encoder/Base64MimeHeaderEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\ContentEncoderInterface' => $vendorDir . '/symfony/mime/Encoder/ContentEncoderInterface.php', + 'Symfony\\Component\\Mime\\Encoder\\EightBitContentEncoder' => $vendorDir . '/symfony/mime/Encoder/EightBitContentEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\EncoderInterface' => $vendorDir . '/symfony/mime/Encoder/EncoderInterface.php', + 'Symfony\\Component\\Mime\\Encoder\\IdnAddressEncoder' => $vendorDir . '/symfony/mime/Encoder/IdnAddressEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\MimeHeaderEncoderInterface' => $vendorDir . '/symfony/mime/Encoder/MimeHeaderEncoderInterface.php', + 'Symfony\\Component\\Mime\\Encoder\\QpContentEncoder' => $vendorDir . '/symfony/mime/Encoder/QpContentEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\QpEncoder' => $vendorDir . '/symfony/mime/Encoder/QpEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\QpMimeHeaderEncoder' => $vendorDir . '/symfony/mime/Encoder/QpMimeHeaderEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\Rfc2231Encoder' => $vendorDir . '/symfony/mime/Encoder/Rfc2231Encoder.php', + 'Symfony\\Component\\Mime\\Exception\\AddressEncoderException' => $vendorDir . '/symfony/mime/Exception/AddressEncoderException.php', + 'Symfony\\Component\\Mime\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/mime/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Mime\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/mime/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Mime\\Exception\\LogicException' => $vendorDir . '/symfony/mime/Exception/LogicException.php', + 'Symfony\\Component\\Mime\\Exception\\RfcComplianceException' => $vendorDir . '/symfony/mime/Exception/RfcComplianceException.php', + 'Symfony\\Component\\Mime\\Exception\\RuntimeException' => $vendorDir . '/symfony/mime/Exception/RuntimeException.php', + 'Symfony\\Component\\Mime\\FileBinaryMimeTypeGuesser' => $vendorDir . '/symfony/mime/FileBinaryMimeTypeGuesser.php', + 'Symfony\\Component\\Mime\\FileinfoMimeTypeGuesser' => $vendorDir . '/symfony/mime/FileinfoMimeTypeGuesser.php', + 'Symfony\\Component\\Mime\\Header\\AbstractHeader' => $vendorDir . '/symfony/mime/Header/AbstractHeader.php', + 'Symfony\\Component\\Mime\\Header\\DateHeader' => $vendorDir . '/symfony/mime/Header/DateHeader.php', + 'Symfony\\Component\\Mime\\Header\\HeaderInterface' => $vendorDir . '/symfony/mime/Header/HeaderInterface.php', + 'Symfony\\Component\\Mime\\Header\\Headers' => $vendorDir . '/symfony/mime/Header/Headers.php', + 'Symfony\\Component\\Mime\\Header\\IdentificationHeader' => $vendorDir . '/symfony/mime/Header/IdentificationHeader.php', + 'Symfony\\Component\\Mime\\Header\\MailboxHeader' => $vendorDir . '/symfony/mime/Header/MailboxHeader.php', + 'Symfony\\Component\\Mime\\Header\\MailboxListHeader' => $vendorDir . '/symfony/mime/Header/MailboxListHeader.php', + 'Symfony\\Component\\Mime\\Header\\ParameterizedHeader' => $vendorDir . '/symfony/mime/Header/ParameterizedHeader.php', + 'Symfony\\Component\\Mime\\Header\\PathHeader' => $vendorDir . '/symfony/mime/Header/PathHeader.php', + 'Symfony\\Component\\Mime\\Header\\UnstructuredHeader' => $vendorDir . '/symfony/mime/Header/UnstructuredHeader.php', + 'Symfony\\Component\\Mime\\HtmlToTextConverter\\DefaultHtmlToTextConverter' => $vendorDir . '/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php', + 'Symfony\\Component\\Mime\\HtmlToTextConverter\\HtmlToTextConverterInterface' => $vendorDir . '/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php', + 'Symfony\\Component\\Mime\\HtmlToTextConverter\\LeagueHtmlToMarkdownConverter' => $vendorDir . '/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php', + 'Symfony\\Component\\Mime\\Message' => $vendorDir . '/symfony/mime/Message.php', + 'Symfony\\Component\\Mime\\MessageConverter' => $vendorDir . '/symfony/mime/MessageConverter.php', + 'Symfony\\Component\\Mime\\MimeTypeGuesserInterface' => $vendorDir . '/symfony/mime/MimeTypeGuesserInterface.php', + 'Symfony\\Component\\Mime\\MimeTypes' => $vendorDir . '/symfony/mime/MimeTypes.php', + 'Symfony\\Component\\Mime\\MimeTypesInterface' => $vendorDir . '/symfony/mime/MimeTypesInterface.php', + 'Symfony\\Component\\Mime\\Part\\AbstractMultipartPart' => $vendorDir . '/symfony/mime/Part/AbstractMultipartPart.php', + 'Symfony\\Component\\Mime\\Part\\AbstractPart' => $vendorDir . '/symfony/mime/Part/AbstractPart.php', + 'Symfony\\Component\\Mime\\Part\\DataPart' => $vendorDir . '/symfony/mime/Part/DataPart.php', + 'Symfony\\Component\\Mime\\Part\\File' => $vendorDir . '/symfony/mime/Part/File.php', + 'Symfony\\Component\\Mime\\Part\\MessagePart' => $vendorDir . '/symfony/mime/Part/MessagePart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\AlternativePart' => $vendorDir . '/symfony/mime/Part/Multipart/AlternativePart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\DigestPart' => $vendorDir . '/symfony/mime/Part/Multipart/DigestPart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\FormDataPart' => $vendorDir . '/symfony/mime/Part/Multipart/FormDataPart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\MixedPart' => $vendorDir . '/symfony/mime/Part/Multipart/MixedPart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\RelatedPart' => $vendorDir . '/symfony/mime/Part/Multipart/RelatedPart.php', + 'Symfony\\Component\\Mime\\Part\\SMimePart' => $vendorDir . '/symfony/mime/Part/SMimePart.php', + 'Symfony\\Component\\Mime\\Part\\TextPart' => $vendorDir . '/symfony/mime/Part/TextPart.php', + 'Symfony\\Component\\Mime\\RawMessage' => $vendorDir . '/symfony/mime/RawMessage.php', 'Symfony\\Component\\Routing\\Alias' => $vendorDir . '/symfony/routing/Alias.php', 'Symfony\\Component\\Routing\\Annotation\\Route' => $vendorDir . '/symfony/routing/Annotation/Route.php', 'Symfony\\Component\\Routing\\Attribute\\Route' => $vendorDir . '/symfony/routing/Attribute/Route.php', @@ -2891,7 +2796,6 @@ return array( 'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\Regex' => $vendorDir . '/symfony/polyfill-intl-idn/Resources/unidata/Regex.php', 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Normalizer.php', 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php', - 'Symfony\\Polyfill\\Php72\\Php72' => $vendorDir . '/symfony/polyfill-php72/Php72.php', 'Symfony\\Polyfill\\Php80\\Php80' => $vendorDir . '/symfony/polyfill-php80/Php80.php', 'Symfony\\Polyfill\\Php80\\PhpToken' => $vendorDir . '/symfony/polyfill-php80/PhpToken.php', 'Symfony\\Polyfill\\Php83\\Php83' => $vendorDir . '/symfony/polyfill-php83/Php83.php', @@ -3218,9 +3122,6 @@ return array( 'VariableExpression' => $baseDir . '/core/oql/expression.class.inc.php', 'VariableOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php', 'WebPageMenuNode' => $baseDir . '/application/menunode.class.inc.php', - 'Webmozart\\Assert\\Assert' => $vendorDir . '/webmozart/assert/src/Assert.php', - 'Webmozart\\Assert\\InvalidArgumentException' => $vendorDir . '/webmozart/assert/src/InvalidArgumentException.php', - 'Webmozart\\Assert\\Mixin' => $vendorDir . '/webmozart/assert/src/Mixin.php', 'WeeklyRotatingLogFileNameBuilder' => $baseDir . '/core/log.class.inc.php', 'WizardHelper' => $baseDir . '/application/wizardhelper.class.inc.php', 'XLSXWriter' => $baseDir . '/application/xlsxwriter.class.php', diff --git a/lib/composer/autoload_files.php b/lib/composer/autoload_files.php index 5359c3175..2ddea1d64 100644 --- a/lib/composer/autoload_files.php +++ b/lib/composer/autoload_files.php @@ -12,17 +12,15 @@ return array( 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', + 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', '89efb1254ef2d1c5d80096acd12c4098' => $vendorDir . '/twig/twig/src/Resources/core.php', 'ffecb95d45175fd40f75be8a23b34f90' => $vendorDir . '/twig/twig/src/Resources/debug.php', 'c7baa00073ee9c61edf148c51917cfb4' => $vendorDir . '/twig/twig/src/Resources/escaper.php', 'f844ccf1d25df8663951193c3fc307c8' => $vendorDir . '/twig/twig/src/Resources/string_loader.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', - 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', - '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', - 'c9d07b32a2e02bc0fc582d4f0c1b56cc' => $vendorDir . '/laminas/laminas-servicemanager/src/autoload.php', - '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', - '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', + '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', + '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php', '344f11dc3484aaed5cbde58e23513be4' => $vendorDir . '/apereo/phpcas/source/CAS.php', '6997bc0ca52a383ea79e2a4a84bb1f3e' => $baseDir . '/sources/alias.php', diff --git a/lib/composer/autoload_psr4.php b/lib/composer/autoload_psr4.php index 078278cb1..7acbed6bf 100644 --- a/lib/composer/autoload_psr4.php +++ b/lib/composer/autoload_psr4.php @@ -6,13 +6,11 @@ $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( - 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), 'Twig\\' => array($vendorDir . '/twig/twig/src'), 'TheNetworg\\OAuth2\\Client\\' => array($vendorDir . '/thenetworg/oauth2-azure/src'), 'Symfony\\Runtime\\Symfony\\Component\\' => array($vendorDir . '/symfony/runtime/Internal'), 'Symfony\\Polyfill\\Php83\\' => array($vendorDir . '/symfony/polyfill-php83'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), - 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), @@ -29,6 +27,8 @@ return array( 'Symfony\\Component\\Stopwatch\\' => array($vendorDir . '/symfony/stopwatch'), 'Symfony\\Component\\Runtime\\' => array($vendorDir . '/symfony/runtime'), 'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'), + 'Symfony\\Component\\Mime\\' => array($vendorDir . '/symfony/mime'), + 'Symfony\\Component\\Mailer\\' => array($vendorDir . '/symfony/mailer'), 'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'), 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'), 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'), @@ -58,14 +58,10 @@ return array( 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), 'Pelago\\Emogrifier\\' => array($vendorDir . '/pelago/emogrifier/src'), 'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-google/src', $vendorDir . '/league/oauth2-client/src'), - 'Laminas\\Validator\\' => array($vendorDir . '/laminas/laminas-validator/src'), - 'Laminas\\Stdlib\\' => array($vendorDir . '/laminas/laminas-stdlib/src'), - 'Laminas\\ServiceManager\\' => array($vendorDir . '/laminas/laminas-servicemanager/src'), - 'Laminas\\Mime\\' => array($vendorDir . '/laminas/laminas-mime/src'), - 'Laminas\\Mail\\' => array($vendorDir . '/laminas/laminas-mail/src'), - 'Laminas\\Loader\\' => array($vendorDir . '/laminas/laminas-loader/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'), + 'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'), + 'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/src'), ); diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index 28f73b6f6..a7ccc0f21 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -13,27 +13,21 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', + 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', '89efb1254ef2d1c5d80096acd12c4098' => __DIR__ . '/..' . '/twig/twig/src/Resources/core.php', 'ffecb95d45175fd40f75be8a23b34f90' => __DIR__ . '/..' . '/twig/twig/src/Resources/debug.php', 'c7baa00073ee9c61edf148c51917cfb4' => __DIR__ . '/..' . '/twig/twig/src/Resources/escaper.php', 'f844ccf1d25df8663951193c3fc307c8' => __DIR__ . '/..' . '/twig/twig/src/Resources/string_loader.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', - 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', - '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', - 'c9d07b32a2e02bc0fc582d4f0c1b56cc' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/autoload.php', - '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', - '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', + '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', + '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php', '344f11dc3484aaed5cbde58e23513be4' => __DIR__ . '/..' . '/apereo/phpcas/source/CAS.php', '6997bc0ca52a383ea79e2a4a84bb1f3e' => __DIR__ . '/../..' . '/sources/alias.php', ); public static $prefixLengthsPsr4 = array ( - 'W' => - array ( - 'Webmozart\\Assert\\' => 17, - ), 'T' => array ( 'Twig\\' => 5, @@ -44,7 +38,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Runtime\\Symfony\\Component\\' => 34, 'Symfony\\Polyfill\\Php83\\' => 23, 'Symfony\\Polyfill\\Php80\\' => 23, - 'Symfony\\Polyfill\\Php72\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, 'Symfony\\Polyfill\\Intl\\Idn\\' => 26, @@ -61,6 +54,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Component\\Stopwatch\\' => 28, 'Symfony\\Component\\Runtime\\' => 26, 'Symfony\\Component\\Routing\\' => 26, + 'Symfony\\Component\\Mime\\' => 23, + 'Symfony\\Component\\Mailer\\' => 25, 'Symfony\\Component\\HttpKernel\\' => 29, 'Symfony\\Component\\HttpFoundation\\' => 33, 'Symfony\\Component\\Finder\\' => 25, @@ -96,12 +91,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'L' => array ( 'League\\OAuth2\\Client\\' => 21, - 'Laminas\\Validator\\' => 18, - 'Laminas\\Stdlib\\' => 15, - 'Laminas\\ServiceManager\\' => 23, - 'Laminas\\Mime\\' => 13, - 'Laminas\\Mail\\' => 13, - 'Laminas\\Loader\\' => 15, ), 'G' => array ( @@ -113,13 +102,17 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f array ( 'Firebase\\JWT\\' => 13, ), + 'E' => + array ( + 'Egulias\\EmailValidator\\' => 23, + ), + 'D' => + array ( + 'Doctrine\\Common\\Lexer\\' => 22, + ), ); public static $prefixDirsPsr4 = array ( - 'Webmozart\\Assert\\' => - array ( - 0 => __DIR__ . '/..' . '/webmozart/assert/src', - ), 'Twig\\' => array ( 0 => __DIR__ . '/..' . '/twig/twig/src', @@ -140,10 +133,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', ), - 'Symfony\\Polyfill\\Php72\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', - ), 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', @@ -208,6 +197,14 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f array ( 0 => __DIR__ . '/..' . '/symfony/routing', ), + 'Symfony\\Component\\Mime\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/mime', + ), + 'Symfony\\Component\\Mailer\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/mailer', + ), 'Symfony\\Component\\HttpKernel\\' => array ( 0 => __DIR__ . '/..' . '/symfony/http-kernel', @@ -326,30 +323,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 0 => __DIR__ . '/..' . '/league/oauth2-google/src', 1 => __DIR__ . '/..' . '/league/oauth2-client/src', ), - 'Laminas\\Validator\\' => - array ( - 0 => __DIR__ . '/..' . '/laminas/laminas-validator/src', - ), - 'Laminas\\Stdlib\\' => - array ( - 0 => __DIR__ . '/..' . '/laminas/laminas-stdlib/src', - ), - 'Laminas\\ServiceManager\\' => - array ( - 0 => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src', - ), - 'Laminas\\Mime\\' => - array ( - 0 => __DIR__ . '/..' . '/laminas/laminas-mime/src', - ), - 'Laminas\\Mail\\' => - array ( - 0 => __DIR__ . '/..' . '/laminas/laminas-mail/src', - ), - 'Laminas\\Loader\\' => - array ( - 0 => __DIR__ . '/..' . '/laminas/laminas-loader/src', - ), 'GuzzleHttp\\Psr7\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src', @@ -366,6 +339,14 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f array ( 0 => __DIR__ . '/..' . '/firebase/php-jwt/src', ), + 'Egulias\\EmailValidator\\' => + array ( + 0 => __DIR__ . '/..' . '/egulias/email-validator/src', + ), + 'Doctrine\\Common\\Lexer\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/lexer/src', + ), ); public static $prefixesPsr0 = array ( @@ -797,11 +778,12 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderAzure' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAzure.php', 'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderFactory' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderFactory.php', 'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderGoogle' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php', - 'Combodo\\iTop\\Core\\Authentication\\Client\\Smtp\\Oauth' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/Smtp/Oauth.php', 'Combodo\\iTop\\Core\\CMDBChange\\CMDBChangeOrigin' => __DIR__ . '/../..' . '/sources/Core/CMDBChange/CMDBChangeOrigin.php', 'Combodo\\iTop\\Core\\DbConnectionWrapper' => __DIR__ . '/../..' . '/core/DbConnectionWrapper.php', - 'Combodo\\iTop\\Core\\Email\\EMailLaminas' => __DIR__ . '/../..' . '/sources/Core/Email/EmailLaminas.php', + 'Combodo\\iTop\\Core\\Email\\EMailSymfony' => __DIR__ . '/../..' . '/sources/Core/Email/EmailSymfony.php', 'Combodo\\iTop\\Core\\Email\\EmailFactory' => __DIR__ . '/../..' . '/sources/Core/Email/EmailFactory.php', + 'Combodo\\iTop\\Core\\Email\\Transport\\SymfonyFileTransport' => __DIR__ . '/../..' . '/sources/Core/Email/Transport/SymfonyFileTransport.php', + 'Combodo\\iTop\\Core\\Email\\Transport\\SymfonyOAuthTransport' => __DIR__ . '/../..' . '/sources/Core/Email/Transport/SymfonyOAuthTransport.php', 'Combodo\\iTop\\Core\\Email\\iEMail' => __DIR__ . '/../..' . '/sources/Core/Email/iEMail.php', 'Combodo\\iTop\\Core\\EventListener\\AttributeBlobEventListener' => __DIR__ . '/../..' . '/sources/Core/EventListener/AttributeBlobEventListener.php', 'Combodo\\iTop\\Core\\Kpi\\KpiLogData' => __DIR__ . '/../..' . '/sources/Core/Kpi/KpiLogData.php', @@ -1003,7 +985,96 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'DisplayableGroupNode' => __DIR__ . '/../..' . '/core/displayablegraph.class.inc.php', 'DisplayableNode' => __DIR__ . '/../..' . '/core/displayablegraph.class.inc.php', 'DisplayableRedundancyNode' => __DIR__ . '/../..' . '/core/displayablegraph.class.inc.php', + 'Doctrine\\Common\\Lexer\\AbstractLexer' => __DIR__ . '/..' . '/doctrine/lexer/src/AbstractLexer.php', + 'Doctrine\\Common\\Lexer\\Token' => __DIR__ . '/..' . '/doctrine/lexer/src/Token.php', 'EMail' => __DIR__ . '/../..' . '/core/email.class.inc.php', + 'Egulias\\EmailValidator\\EmailLexer' => __DIR__ . '/..' . '/egulias/email-validator/src/EmailLexer.php', + 'Egulias\\EmailValidator\\EmailParser' => __DIR__ . '/..' . '/egulias/email-validator/src/EmailParser.php', + 'Egulias\\EmailValidator\\EmailValidator' => __DIR__ . '/..' . '/egulias/email-validator/src/EmailValidator.php', + 'Egulias\\EmailValidator\\MessageIDParser' => __DIR__ . '/..' . '/egulias/email-validator/src/MessageIDParser.php', + 'Egulias\\EmailValidator\\Parser' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser.php', + 'Egulias\\EmailValidator\\Parser\\Comment' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/Comment.php', + 'Egulias\\EmailValidator\\Parser\\CommentStrategy\\CommentStrategy' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php', + 'Egulias\\EmailValidator\\Parser\\CommentStrategy\\DomainComment' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/CommentStrategy/DomainComment.php', + 'Egulias\\EmailValidator\\Parser\\CommentStrategy\\LocalComment' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php', + 'Egulias\\EmailValidator\\Parser\\DomainLiteral' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/DomainLiteral.php', + 'Egulias\\EmailValidator\\Parser\\DomainPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/DomainPart.php', + 'Egulias\\EmailValidator\\Parser\\DoubleQuote' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/DoubleQuote.php', + 'Egulias\\EmailValidator\\Parser\\FoldingWhiteSpace' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/FoldingWhiteSpace.php', + 'Egulias\\EmailValidator\\Parser\\IDLeftPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/IDLeftPart.php', + 'Egulias\\EmailValidator\\Parser\\IDRightPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/IDRightPart.php', + 'Egulias\\EmailValidator\\Parser\\LocalPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/LocalPart.php', + 'Egulias\\EmailValidator\\Parser\\PartParser' => __DIR__ . '/..' . '/egulias/email-validator/src/Parser/PartParser.php', + 'Egulias\\EmailValidator\\Result\\InvalidEmail' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/InvalidEmail.php', + 'Egulias\\EmailValidator\\Result\\MultipleErrors' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/MultipleErrors.php', + 'Egulias\\EmailValidator\\Result\\Reason\\AtextAfterCFWS' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CRLFAtTheEnd' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/CRLFAtTheEnd.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CRLFX2' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/CRLFX2.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CRNoLF' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/CRNoLF.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CharNotAllowed' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/CharNotAllowed.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CommaInDomain' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/CommaInDomain.php', + 'Egulias\\EmailValidator\\Result\\Reason\\CommentsInIDRight' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/CommentsInIDRight.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ConsecutiveAt' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/ConsecutiveAt.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ConsecutiveDot' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/ConsecutiveDot.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DetailedReason' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/DetailedReason.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DomainAcceptsNoMail' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DomainHyphened' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/DomainHyphened.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DomainTooLong' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/DomainTooLong.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DotAtEnd' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/DotAtEnd.php', + 'Egulias\\EmailValidator\\Result\\Reason\\DotAtStart' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/DotAtStart.php', + 'Egulias\\EmailValidator\\Result\\Reason\\EmptyReason' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/EmptyReason.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExceptionFound' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/ExceptionFound.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExpectingATEXT' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExpectingCTEXT' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExpectingDTEXT' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/ExpectingDTEXT.php', + 'Egulias\\EmailValidator\\Result\\Reason\\ExpectingDomainLiteralClose' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/ExpectingDomainLiteralClose.php', + 'Egulias\\EmailValidator\\Result\\Reason\\LabelTooLong' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/LabelTooLong.php', + 'Egulias\\EmailValidator\\Result\\Reason\\LocalOrReservedDomain' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/LocalOrReservedDomain.php', + 'Egulias\\EmailValidator\\Result\\Reason\\NoDNSRecord' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/NoDNSRecord.php', + 'Egulias\\EmailValidator\\Result\\Reason\\NoDomainPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/NoDomainPart.php', + 'Egulias\\EmailValidator\\Result\\Reason\\NoLocalPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/NoLocalPart.php', + 'Egulias\\EmailValidator\\Result\\Reason\\RFCWarnings' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/RFCWarnings.php', + 'Egulias\\EmailValidator\\Result\\Reason\\Reason' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/Reason.php', + 'Egulias\\EmailValidator\\Result\\Reason\\SpoofEmail' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/SpoofEmail.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnOpenedComment' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/UnOpenedComment.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnableToGetDNSRecord' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/UnableToGetDNSRecord.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnclosedComment' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/UnclosedComment.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnclosedQuotedString' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/UnclosedQuotedString.php', + 'Egulias\\EmailValidator\\Result\\Reason\\UnusualElements' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Reason/UnusualElements.php', + 'Egulias\\EmailValidator\\Result\\Result' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/Result.php', + 'Egulias\\EmailValidator\\Result\\SpoofEmail' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/SpoofEmail.php', + 'Egulias\\EmailValidator\\Result\\ValidEmail' => __DIR__ . '/..' . '/egulias/email-validator/src/Result/ValidEmail.php', + 'Egulias\\EmailValidator\\Validation\\DNSCheckValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/DNSCheckValidation.php', + 'Egulias\\EmailValidator\\Validation\\DNSGetRecordWrapper' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php', + 'Egulias\\EmailValidator\\Validation\\DNSRecords' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/DNSRecords.php', + 'Egulias\\EmailValidator\\Validation\\EmailValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/EmailValidation.php', + 'Egulias\\EmailValidator\\Validation\\Exception\\EmptyValidationList' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/Exception/EmptyValidationList.php', + 'Egulias\\EmailValidator\\Validation\\Extra\\SpoofCheckValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/Extra/SpoofCheckValidation.php', + 'Egulias\\EmailValidator\\Validation\\MessageIDValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/MessageIDValidation.php', + 'Egulias\\EmailValidator\\Validation\\MultipleValidationWithAnd' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php', + 'Egulias\\EmailValidator\\Validation\\NoRFCWarningsValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php', + 'Egulias\\EmailValidator\\Validation\\RFCValidation' => __DIR__ . '/..' . '/egulias/email-validator/src/Validation/RFCValidation.php', + 'Egulias\\EmailValidator\\Warning\\AddressLiteral' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/AddressLiteral.php', + 'Egulias\\EmailValidator\\Warning\\CFWSNearAt' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/CFWSNearAt.php', + 'Egulias\\EmailValidator\\Warning\\CFWSWithFWS' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/CFWSWithFWS.php', + 'Egulias\\EmailValidator\\Warning\\Comment' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/Comment.php', + 'Egulias\\EmailValidator\\Warning\\DeprecatedComment' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/DeprecatedComment.php', + 'Egulias\\EmailValidator\\Warning\\DomainLiteral' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/DomainLiteral.php', + 'Egulias\\EmailValidator\\Warning\\EmailTooLong' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/EmailTooLong.php', + 'Egulias\\EmailValidator\\Warning\\IPV6BadChar' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6BadChar.php', + 'Egulias\\EmailValidator\\Warning\\IPV6ColonEnd' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6ColonEnd.php', + 'Egulias\\EmailValidator\\Warning\\IPV6ColonStart' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6ColonStart.php', + 'Egulias\\EmailValidator\\Warning\\IPV6Deprecated' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6Deprecated.php', + 'Egulias\\EmailValidator\\Warning\\IPV6DoubleColon' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6DoubleColon.php', + 'Egulias\\EmailValidator\\Warning\\IPV6GroupCount' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6GroupCount.php', + 'Egulias\\EmailValidator\\Warning\\IPV6MaxGroups' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/IPV6MaxGroups.php', + 'Egulias\\EmailValidator\\Warning\\LocalTooLong' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/LocalTooLong.php', + 'Egulias\\EmailValidator\\Warning\\NoDNSMXRecord' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/NoDNSMXRecord.php', + 'Egulias\\EmailValidator\\Warning\\ObsoleteDTEXT' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/ObsoleteDTEXT.php', + 'Egulias\\EmailValidator\\Warning\\QuotedPart' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/QuotedPart.php', + 'Egulias\\EmailValidator\\Warning\\QuotedString' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/QuotedString.php', + 'Egulias\\EmailValidator\\Warning\\TLD' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/TLD.php', + 'Egulias\\EmailValidator\\Warning\\Warning' => __DIR__ . '/..' . '/egulias/email-validator/src/Warning/Warning.php', 'Event' => __DIR__ . '/../..' . '/core/event.class.inc.php', 'EventIssue' => __DIR__ . '/../..' . '/core/event.class.inc.php', 'EventLoginUsage' => __DIR__ . '/../..' . '/core/event.class.inc.php', @@ -1148,321 +1219,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'JSButtonItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php', 'JSPopupMenuItem' => __DIR__ . '/../..' . '/application/applicationextension.inc.php', 'KeyValueStore' => __DIR__ . '/../..' . '/core/counter.class.inc.php', - 'Laminas\\Loader\\AutoloaderFactory' => __DIR__ . '/..' . '/laminas/laminas-loader/src/AutoloaderFactory.php', - 'Laminas\\Loader\\ClassMapAutoloader' => __DIR__ . '/..' . '/laminas/laminas-loader/src/ClassMapAutoloader.php', - 'Laminas\\Loader\\Exception\\BadMethodCallException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/BadMethodCallException.php', - 'Laminas\\Loader\\Exception\\DomainException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/DomainException.php', - 'Laminas\\Loader\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/ExceptionInterface.php', - 'Laminas\\Loader\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/InvalidArgumentException.php', - 'Laminas\\Loader\\Exception\\InvalidPathException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/InvalidPathException.php', - 'Laminas\\Loader\\Exception\\MissingResourceNamespaceException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/MissingResourceNamespaceException.php', - 'Laminas\\Loader\\Exception\\PluginLoaderException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/PluginLoaderException.php', - 'Laminas\\Loader\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/RuntimeException.php', - 'Laminas\\Loader\\Exception\\SecurityException' => __DIR__ . '/..' . '/laminas/laminas-loader/src/Exception/SecurityException.php', - 'Laminas\\Loader\\ModuleAutoloader' => __DIR__ . '/..' . '/laminas/laminas-loader/src/ModuleAutoloader.php', - 'Laminas\\Loader\\PluginClassLoader' => __DIR__ . '/..' . '/laminas/laminas-loader/src/PluginClassLoader.php', - 'Laminas\\Loader\\PluginClassLocator' => __DIR__ . '/..' . '/laminas/laminas-loader/src/PluginClassLocator.php', - 'Laminas\\Loader\\ShortNameLocator' => __DIR__ . '/..' . '/laminas/laminas-loader/src/ShortNameLocator.php', - 'Laminas\\Loader\\SplAutoloader' => __DIR__ . '/..' . '/laminas/laminas-loader/src/SplAutoloader.php', - 'Laminas\\Loader\\StandardAutoloader' => __DIR__ . '/..' . '/laminas/laminas-loader/src/StandardAutoloader.php', - 'Laminas\\Mail\\Address' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Address.php', - 'Laminas\\Mail\\AddressList' => __DIR__ . '/..' . '/laminas/laminas-mail/src/AddressList.php', - 'Laminas\\Mail\\Address\\AddressInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Address/AddressInterface.php', - 'Laminas\\Mail\\ConfigProvider' => __DIR__ . '/..' . '/laminas/laminas-mail/src/ConfigProvider.php', - 'Laminas\\Mail\\Exception\\BadMethodCallException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Exception/BadMethodCallException.php', - 'Laminas\\Mail\\Exception\\DomainException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Exception/DomainException.php', - 'Laminas\\Mail\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Exception\\OutOfBoundsException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Exception/OutOfBoundsException.php', - 'Laminas\\Mail\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Exception/RuntimeException.php', - 'Laminas\\Mail\\Header\\AbstractAddressList' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/AbstractAddressList.php', - 'Laminas\\Mail\\Header\\Bcc' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Bcc.php', - 'Laminas\\Mail\\Header\\Cc' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Cc.php', - 'Laminas\\Mail\\Header\\ContentDisposition' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/ContentDisposition.php', - 'Laminas\\Mail\\Header\\ContentTransferEncoding' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/ContentTransferEncoding.php', - 'Laminas\\Mail\\Header\\ContentType' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/ContentType.php', - 'Laminas\\Mail\\Header\\Date' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Date.php', - 'Laminas\\Mail\\Header\\Exception\\BadMethodCallException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Exception/BadMethodCallException.php', - 'Laminas\\Mail\\Header\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Header\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Header\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Exception/RuntimeException.php', - 'Laminas\\Mail\\Header\\From' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/From.php', - 'Laminas\\Mail\\Header\\GenericHeader' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/GenericHeader.php', - 'Laminas\\Mail\\Header\\GenericMultiHeader' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/GenericMultiHeader.php', - 'Laminas\\Mail\\Header\\HeaderInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/HeaderInterface.php', - 'Laminas\\Mail\\Header\\HeaderLoader' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/HeaderLoader.php', - 'Laminas\\Mail\\Header\\HeaderLocator' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/HeaderLocator.php', - 'Laminas\\Mail\\Header\\HeaderLocatorInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/HeaderLocatorInterface.php', - 'Laminas\\Mail\\Header\\HeaderName' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/HeaderName.php', - 'Laminas\\Mail\\Header\\HeaderValue' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/HeaderValue.php', - 'Laminas\\Mail\\Header\\HeaderWrap' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/HeaderWrap.php', - 'Laminas\\Mail\\Header\\IdentificationField' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/IdentificationField.php', - 'Laminas\\Mail\\Header\\InReplyTo' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/InReplyTo.php', - 'Laminas\\Mail\\Header\\ListParser' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/ListParser.php', - 'Laminas\\Mail\\Header\\MessageId' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/MessageId.php', - 'Laminas\\Mail\\Header\\MimeVersion' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/MimeVersion.php', - 'Laminas\\Mail\\Header\\MultipleHeadersInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/MultipleHeadersInterface.php', - 'Laminas\\Mail\\Header\\Received' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Received.php', - 'Laminas\\Mail\\Header\\References' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/References.php', - 'Laminas\\Mail\\Header\\ReplyTo' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/ReplyTo.php', - 'Laminas\\Mail\\Header\\Sender' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Sender.php', - 'Laminas\\Mail\\Header\\StructuredInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/StructuredInterface.php', - 'Laminas\\Mail\\Header\\Subject' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/Subject.php', - 'Laminas\\Mail\\Header\\To' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/To.php', - 'Laminas\\Mail\\Header\\UnstructuredInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Header/UnstructuredInterface.php', - 'Laminas\\Mail\\Headers' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Headers.php', - 'Laminas\\Mail\\Message' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Message.php', - 'Laminas\\Mail\\MessageFactory' => __DIR__ . '/..' . '/laminas/laminas-mail/src/MessageFactory.php', - 'Laminas\\Mail\\Module' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Module.php', - 'Laminas\\Mail\\Protocol\\AbstractProtocol' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/AbstractProtocol.php', - 'Laminas\\Mail\\Protocol\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Protocol\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Protocol\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Exception/RuntimeException.php', - 'Laminas\\Mail\\Protocol\\Imap' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Imap.php', - 'Laminas\\Mail\\Protocol\\Pop3' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Pop3.php', - 'Laminas\\Mail\\Protocol\\Pop3\\Response' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Pop3/Response.php', - 'Laminas\\Mail\\Protocol\\Pop3\\Xoauth2\\Microsoft' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Pop3/Xoauth2/Microsoft.php', - 'Laminas\\Mail\\Protocol\\ProtocolTrait' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/ProtocolTrait.php', - 'Laminas\\Mail\\Protocol\\Smtp' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp.php', - 'Laminas\\Mail\\Protocol\\SmtpPluginManager' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php', - 'Laminas\\Mail\\Protocol\\SmtpPluginManagerFactory' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/SmtpPluginManagerFactory.php', - 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Crammd5' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php', - 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Login' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php', - 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Plain' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php', - 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Xoauth2' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Smtp/Auth/Xoauth2.php', - 'Laminas\\Mail\\Protocol\\Xoauth2\\Xoauth2' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Protocol/Xoauth2/Xoauth2.php', - 'Laminas\\Mail\\Storage' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage.php', - 'Laminas\\Mail\\Storage\\AbstractStorage' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/AbstractStorage.php', - 'Laminas\\Mail\\Storage\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Storage\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Storage\\Exception\\OutOfBoundsException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Exception/OutOfBoundsException.php', - 'Laminas\\Mail\\Storage\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Exception/RuntimeException.php', - 'Laminas\\Mail\\Storage\\Folder' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Folder.php', - 'Laminas\\Mail\\Storage\\Folder\\FolderInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Folder/FolderInterface.php', - 'Laminas\\Mail\\Storage\\Folder\\Maildir' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Folder/Maildir.php', - 'Laminas\\Mail\\Storage\\Folder\\Mbox' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Folder/Mbox.php', - 'Laminas\\Mail\\Storage\\Imap' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Imap.php', - 'Laminas\\Mail\\Storage\\Maildir' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Maildir.php', - 'Laminas\\Mail\\Storage\\Mbox' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Mbox.php', - 'Laminas\\Mail\\Storage\\Message' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Message.php', - 'Laminas\\Mail\\Storage\\Message\\File' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Message/File.php', - 'Laminas\\Mail\\Storage\\Message\\MessageInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Message/MessageInterface.php', - 'Laminas\\Mail\\Storage\\ParamsNormalizer' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/ParamsNormalizer.php', - 'Laminas\\Mail\\Storage\\Part' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Part.php', - 'Laminas\\Mail\\Storage\\Part\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Part/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Storage\\Part\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Part/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Storage\\Part\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Part/Exception/RuntimeException.php', - 'Laminas\\Mail\\Storage\\Part\\File' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Part/File.php', - 'Laminas\\Mail\\Storage\\Part\\PartInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Part/PartInterface.php', - 'Laminas\\Mail\\Storage\\Pop3' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Pop3.php', - 'Laminas\\Mail\\Storage\\Writable\\Maildir' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Writable/Maildir.php', - 'Laminas\\Mail\\Storage\\Writable\\WritableInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Storage/Writable/WritableInterface.php', - 'Laminas\\Mail\\Transport\\Envelope' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/Envelope.php', - 'Laminas\\Mail\\Transport\\Exception\\DomainException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/Exception/DomainException.php', - 'Laminas\\Mail\\Transport\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/Exception/ExceptionInterface.php', - 'Laminas\\Mail\\Transport\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/Exception/InvalidArgumentException.php', - 'Laminas\\Mail\\Transport\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/Exception/RuntimeException.php', - 'Laminas\\Mail\\Transport\\Factory' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/Factory.php', - 'Laminas\\Mail\\Transport\\File' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/File.php', - 'Laminas\\Mail\\Transport\\FileOptions' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/FileOptions.php', - 'Laminas\\Mail\\Transport\\InMemory' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/InMemory.php', - 'Laminas\\Mail\\Transport\\Sendmail' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/Sendmail.php', - 'Laminas\\Mail\\Transport\\Smtp' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/Smtp.php', - 'Laminas\\Mail\\Transport\\SmtpOptions' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/SmtpOptions.php', - 'Laminas\\Mail\\Transport\\TransportInterface' => __DIR__ . '/..' . '/laminas/laminas-mail/src/Transport/TransportInterface.php', - 'Laminas\\Mime\\Decode' => __DIR__ . '/..' . '/laminas/laminas-mime/src/Decode.php', - 'Laminas\\Mime\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-mime/src/Exception/ExceptionInterface.php', - 'Laminas\\Mime\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-mime/src/Exception/InvalidArgumentException.php', - 'Laminas\\Mime\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-mime/src/Exception/RuntimeException.php', - 'Laminas\\Mime\\Message' => __DIR__ . '/..' . '/laminas/laminas-mime/src/Message.php', - 'Laminas\\Mime\\Mime' => __DIR__ . '/..' . '/laminas/laminas-mime/src/Mime.php', - 'Laminas\\Mime\\Part' => __DIR__ . '/..' . '/laminas/laminas-mime/src/Part.php', - 'Laminas\\ServiceManager\\AbstractFactoryInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/AbstractFactoryInterface.php', - 'Laminas\\ServiceManager\\AbstractFactory\\ConfigAbstractFactory' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/AbstractFactory/ConfigAbstractFactory.php', - 'Laminas\\ServiceManager\\AbstractFactory\\ReflectionBasedAbstractFactory' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/AbstractFactory/ReflectionBasedAbstractFactory.php', - 'Laminas\\ServiceManager\\AbstractPluginManager' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/AbstractPluginManager.php', - 'Laminas\\ServiceManager\\Config' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Config.php', - 'Laminas\\ServiceManager\\ConfigInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/ConfigInterface.php', - 'Laminas\\ServiceManager\\DelegatorFactoryInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/DelegatorFactoryInterface.php', - 'Laminas\\ServiceManager\\Exception\\ContainerModificationsNotAllowedException' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Exception/ContainerModificationsNotAllowedException.php', - 'Laminas\\ServiceManager\\Exception\\CyclicAliasException' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Exception/CyclicAliasException.php', - 'Laminas\\ServiceManager\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Exception/ExceptionInterface.php', - 'Laminas\\ServiceManager\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Exception/InvalidArgumentException.php', - 'Laminas\\ServiceManager\\Exception\\InvalidServiceException' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Exception/InvalidServiceException.php', - 'Laminas\\ServiceManager\\Exception\\ServiceNotCreatedException' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Exception/ServiceNotCreatedException.php', - 'Laminas\\ServiceManager\\Exception\\ServiceNotFoundException' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Exception/ServiceNotFoundException.php', - 'Laminas\\ServiceManager\\FactoryInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/FactoryInterface.php', - 'Laminas\\ServiceManager\\Factory\\AbstractFactoryInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Factory/AbstractFactoryInterface.php', - 'Laminas\\ServiceManager\\Factory\\DelegatorFactoryInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Factory/DelegatorFactoryInterface.php', - 'Laminas\\ServiceManager\\Factory\\FactoryInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Factory/FactoryInterface.php', - 'Laminas\\ServiceManager\\Factory\\InvokableFactory' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Factory/InvokableFactory.php', - 'Laminas\\ServiceManager\\InitializerInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/InitializerInterface.php', - 'Laminas\\ServiceManager\\Initializer\\InitializerInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Initializer/InitializerInterface.php', - 'Laminas\\ServiceManager\\PluginManagerInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/PluginManagerInterface.php', - 'Laminas\\ServiceManager\\Proxy\\LazyServiceFactory' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Proxy/LazyServiceFactory.php', - 'Laminas\\ServiceManager\\ServiceLocatorInterface' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/ServiceLocatorInterface.php', - 'Laminas\\ServiceManager\\ServiceManager' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/ServiceManager.php', - 'Laminas\\ServiceManager\\Tool\\ConfigDumper' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Tool/ConfigDumper.php', - 'Laminas\\ServiceManager\\Tool\\ConfigDumperCommand' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Tool/ConfigDumperCommand.php', - 'Laminas\\ServiceManager\\Tool\\FactoryCreator' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Tool/FactoryCreator.php', - 'Laminas\\ServiceManager\\Tool\\FactoryCreatorCommand' => __DIR__ . '/..' . '/laminas/laminas-servicemanager/src/Tool/FactoryCreatorCommand.php', - 'Laminas\\Stdlib\\AbstractOptions' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/AbstractOptions.php', - 'Laminas\\Stdlib\\ArrayObject' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ArrayObject.php', - 'Laminas\\Stdlib\\ArraySerializableInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ArraySerializableInterface.php', - 'Laminas\\Stdlib\\ArrayStack' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ArrayStack.php', - 'Laminas\\Stdlib\\ArrayUtils' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ArrayUtils.php', - 'Laminas\\Stdlib\\ArrayUtils\\MergeRemoveKey' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ArrayUtils/MergeRemoveKey.php', - 'Laminas\\Stdlib\\ArrayUtils\\MergeReplaceKey' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ArrayUtils/MergeReplaceKey.php', - 'Laminas\\Stdlib\\ArrayUtils\\MergeReplaceKeyInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ArrayUtils/MergeReplaceKeyInterface.php', - 'Laminas\\Stdlib\\ConsoleHelper' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ConsoleHelper.php', - 'Laminas\\Stdlib\\DispatchableInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/DispatchableInterface.php', - 'Laminas\\Stdlib\\ErrorHandler' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ErrorHandler.php', - 'Laminas\\Stdlib\\Exception\\BadMethodCallException' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Exception/BadMethodCallException.php', - 'Laminas\\Stdlib\\Exception\\DomainException' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Exception/DomainException.php', - 'Laminas\\Stdlib\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Exception/ExceptionInterface.php', - 'Laminas\\Stdlib\\Exception\\ExtensionNotLoadedException' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Exception/ExtensionNotLoadedException.php', - 'Laminas\\Stdlib\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Exception/InvalidArgumentException.php', - 'Laminas\\Stdlib\\Exception\\LogicException' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Exception/LogicException.php', - 'Laminas\\Stdlib\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Exception/RuntimeException.php', - 'Laminas\\Stdlib\\FastPriorityQueue' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/FastPriorityQueue.php', - 'Laminas\\Stdlib\\Glob' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Glob.php', - 'Laminas\\Stdlib\\Guard\\AllGuardsTrait' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Guard/AllGuardsTrait.php', - 'Laminas\\Stdlib\\Guard\\ArrayOrTraversableGuardTrait' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Guard/ArrayOrTraversableGuardTrait.php', - 'Laminas\\Stdlib\\Guard\\EmptyGuardTrait' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Guard/EmptyGuardTrait.php', - 'Laminas\\Stdlib\\Guard\\NullGuardTrait' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Guard/NullGuardTrait.php', - 'Laminas\\Stdlib\\InitializableInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/InitializableInterface.php', - 'Laminas\\Stdlib\\JsonSerializable' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/JsonSerializable.php', - 'Laminas\\Stdlib\\Message' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Message.php', - 'Laminas\\Stdlib\\MessageInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/MessageInterface.php', - 'Laminas\\Stdlib\\ParameterObjectInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ParameterObjectInterface.php', - 'Laminas\\Stdlib\\Parameters' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Parameters.php', - 'Laminas\\Stdlib\\ParametersInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ParametersInterface.php', - 'Laminas\\Stdlib\\PriorityList' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/PriorityList.php', - 'Laminas\\Stdlib\\PriorityQueue' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/PriorityQueue.php', - 'Laminas\\Stdlib\\Request' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Request.php', - 'Laminas\\Stdlib\\RequestInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/RequestInterface.php', - 'Laminas\\Stdlib\\Response' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/Response.php', - 'Laminas\\Stdlib\\ResponseInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/ResponseInterface.php', - 'Laminas\\Stdlib\\SplPriorityQueue' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/SplPriorityQueue.php', - 'Laminas\\Stdlib\\SplQueue' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/SplQueue.php', - 'Laminas\\Stdlib\\SplStack' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/SplStack.php', - 'Laminas\\Stdlib\\StringUtils' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/StringUtils.php', - 'Laminas\\Stdlib\\StringWrapper\\AbstractStringWrapper' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/StringWrapper/AbstractStringWrapper.php', - 'Laminas\\Stdlib\\StringWrapper\\Iconv' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/StringWrapper/Iconv.php', - 'Laminas\\Stdlib\\StringWrapper\\Intl' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/StringWrapper/Intl.php', - 'Laminas\\Stdlib\\StringWrapper\\MbString' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/StringWrapper/MbString.php', - 'Laminas\\Stdlib\\StringWrapper\\Native' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/StringWrapper/Native.php', - 'Laminas\\Stdlib\\StringWrapper\\StringWrapperInterface' => __DIR__ . '/..' . '/laminas/laminas-stdlib/src/StringWrapper/StringWrapperInterface.php', - 'Laminas\\Validator\\AbstractValidator' => __DIR__ . '/..' . '/laminas/laminas-validator/src/AbstractValidator.php', - 'Laminas\\Validator\\Barcode' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode.php', - 'Laminas\\Validator\\Barcode\\AbstractAdapter' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/AbstractAdapter.php', - 'Laminas\\Validator\\Barcode\\AdapterInterface' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/AdapterInterface.php', - 'Laminas\\Validator\\Barcode\\Codabar' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Codabar.php', - 'Laminas\\Validator\\Barcode\\Code128' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Code128.php', - 'Laminas\\Validator\\Barcode\\Code25' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Code25.php', - 'Laminas\\Validator\\Barcode\\Code25interleaved' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Code25interleaved.php', - 'Laminas\\Validator\\Barcode\\Code39' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Code39.php', - 'Laminas\\Validator\\Barcode\\Code39ext' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Code39ext.php', - 'Laminas\\Validator\\Barcode\\Code93' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Code93.php', - 'Laminas\\Validator\\Barcode\\Code93ext' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Code93ext.php', - 'Laminas\\Validator\\Barcode\\Ean12' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Ean12.php', - 'Laminas\\Validator\\Barcode\\Ean13' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Ean13.php', - 'Laminas\\Validator\\Barcode\\Ean14' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Ean14.php', - 'Laminas\\Validator\\Barcode\\Ean18' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Ean18.php', - 'Laminas\\Validator\\Barcode\\Ean2' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Ean2.php', - 'Laminas\\Validator\\Barcode\\Ean5' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Ean5.php', - 'Laminas\\Validator\\Barcode\\Ean8' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Ean8.php', - 'Laminas\\Validator\\Barcode\\Gtin12' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Gtin12.php', - 'Laminas\\Validator\\Barcode\\Gtin13' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Gtin13.php', - 'Laminas\\Validator\\Barcode\\Gtin14' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Gtin14.php', - 'Laminas\\Validator\\Barcode\\Identcode' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Identcode.php', - 'Laminas\\Validator\\Barcode\\Intelligentmail' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Intelligentmail.php', - 'Laminas\\Validator\\Barcode\\Issn' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Issn.php', - 'Laminas\\Validator\\Barcode\\Itf14' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Itf14.php', - 'Laminas\\Validator\\Barcode\\Leitcode' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Leitcode.php', - 'Laminas\\Validator\\Barcode\\Planet' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Planet.php', - 'Laminas\\Validator\\Barcode\\Postnet' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Postnet.php', - 'Laminas\\Validator\\Barcode\\Royalmail' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Royalmail.php', - 'Laminas\\Validator\\Barcode\\Sscc' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Sscc.php', - 'Laminas\\Validator\\Barcode\\Upca' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Upca.php', - 'Laminas\\Validator\\Barcode\\Upce' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Barcode/Upce.php', - 'Laminas\\Validator\\Between' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Between.php', - 'Laminas\\Validator\\Bitwise' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Bitwise.php', - 'Laminas\\Validator\\BusinessIdentifierCode' => __DIR__ . '/..' . '/laminas/laminas-validator/src/BusinessIdentifierCode.php', - 'Laminas\\Validator\\Callback' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Callback.php', - 'Laminas\\Validator\\ConfigProvider' => __DIR__ . '/..' . '/laminas/laminas-validator/src/ConfigProvider.php', - 'Laminas\\Validator\\CreditCard' => __DIR__ . '/..' . '/laminas/laminas-validator/src/CreditCard.php', - 'Laminas\\Validator\\Csrf' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Csrf.php', - 'Laminas\\Validator\\Date' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Date.php', - 'Laminas\\Validator\\DateStep' => __DIR__ . '/..' . '/laminas/laminas-validator/src/DateStep.php', - 'Laminas\\Validator\\Db\\AbstractDb' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Db/AbstractDb.php', - 'Laminas\\Validator\\Db\\NoRecordExists' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Db/NoRecordExists.php', - 'Laminas\\Validator\\Db\\RecordExists' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Db/RecordExists.php', - 'Laminas\\Validator\\Digits' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Digits.php', - 'Laminas\\Validator\\EmailAddress' => __DIR__ . '/..' . '/laminas/laminas-validator/src/EmailAddress.php', - 'Laminas\\Validator\\Exception\\BadMethodCallException' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Exception/BadMethodCallException.php', - 'Laminas\\Validator\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Exception/ExceptionInterface.php', - 'Laminas\\Validator\\Exception\\ExtensionNotLoadedException' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Exception/ExtensionNotLoadedException.php', - 'Laminas\\Validator\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Exception/InvalidArgumentException.php', - 'Laminas\\Validator\\Exception\\InvalidMagicMimeFileException' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Exception/InvalidMagicMimeFileException.php', - 'Laminas\\Validator\\Exception\\RuntimeException' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Exception/RuntimeException.php', - 'Laminas\\Validator\\Explode' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Explode.php', - 'Laminas\\Validator\\File\\Count' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Count.php', - 'Laminas\\Validator\\File\\Crc32' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Crc32.php', - 'Laminas\\Validator\\File\\ExcludeExtension' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/ExcludeExtension.php', - 'Laminas\\Validator\\File\\ExcludeMimeType' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/ExcludeMimeType.php', - 'Laminas\\Validator\\File\\Exists' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Exists.php', - 'Laminas\\Validator\\File\\Extension' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Extension.php', - 'Laminas\\Validator\\File\\FileInformationTrait' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/FileInformationTrait.php', - 'Laminas\\Validator\\File\\FilesSize' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/FilesSize.php', - 'Laminas\\Validator\\File\\Hash' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Hash.php', - 'Laminas\\Validator\\File\\ImageSize' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/ImageSize.php', - 'Laminas\\Validator\\File\\IsCompressed' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/IsCompressed.php', - 'Laminas\\Validator\\File\\IsImage' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/IsImage.php', - 'Laminas\\Validator\\File\\Md5' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Md5.php', - 'Laminas\\Validator\\File\\MimeType' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/MimeType.php', - 'Laminas\\Validator\\File\\NotExists' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/NotExists.php', - 'Laminas\\Validator\\File\\Sha1' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Sha1.php', - 'Laminas\\Validator\\File\\Size' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Size.php', - 'Laminas\\Validator\\File\\Upload' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/Upload.php', - 'Laminas\\Validator\\File\\UploadFile' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/UploadFile.php', - 'Laminas\\Validator\\File\\WordCount' => __DIR__ . '/..' . '/laminas/laminas-validator/src/File/WordCount.php', - 'Laminas\\Validator\\GpsPoint' => __DIR__ . '/..' . '/laminas/laminas-validator/src/GpsPoint.php', - 'Laminas\\Validator\\GreaterThan' => __DIR__ . '/..' . '/laminas/laminas-validator/src/GreaterThan.php', - 'Laminas\\Validator\\Hex' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Hex.php', - 'Laminas\\Validator\\Hostname' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Hostname.php', - 'Laminas\\Validator\\Iban' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Iban.php', - 'Laminas\\Validator\\Identical' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Identical.php', - 'Laminas\\Validator\\InArray' => __DIR__ . '/..' . '/laminas/laminas-validator/src/InArray.php', - 'Laminas\\Validator\\Ip' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Ip.php', - 'Laminas\\Validator\\IsCountable' => __DIR__ . '/..' . '/laminas/laminas-validator/src/IsCountable.php', - 'Laminas\\Validator\\IsInstanceOf' => __DIR__ . '/..' . '/laminas/laminas-validator/src/IsInstanceOf.php', - 'Laminas\\Validator\\Isbn' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Isbn.php', - 'Laminas\\Validator\\Isbn\\Isbn10' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Isbn/Isbn10.php', - 'Laminas\\Validator\\Isbn\\Isbn13' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Isbn/Isbn13.php', - 'Laminas\\Validator\\LessThan' => __DIR__ . '/..' . '/laminas/laminas-validator/src/LessThan.php', - 'Laminas\\Validator\\Module' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Module.php', - 'Laminas\\Validator\\NotEmpty' => __DIR__ . '/..' . '/laminas/laminas-validator/src/NotEmpty.php', - 'Laminas\\Validator\\Regex' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Regex.php', - 'Laminas\\Validator\\Sitemap\\Changefreq' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Sitemap/Changefreq.php', - 'Laminas\\Validator\\Sitemap\\Lastmod' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Sitemap/Lastmod.php', - 'Laminas\\Validator\\Sitemap\\Loc' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Sitemap/Loc.php', - 'Laminas\\Validator\\Sitemap\\Priority' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Sitemap/Priority.php', - 'Laminas\\Validator\\StaticValidator' => __DIR__ . '/..' . '/laminas/laminas-validator/src/StaticValidator.php', - 'Laminas\\Validator\\Step' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Step.php', - 'Laminas\\Validator\\StringLength' => __DIR__ . '/..' . '/laminas/laminas-validator/src/StringLength.php', - 'Laminas\\Validator\\Timezone' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Timezone.php', - 'Laminas\\Validator\\Translator\\TranslatorAwareInterface' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Translator/TranslatorAwareInterface.php', - 'Laminas\\Validator\\Translator\\TranslatorInterface' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Translator/TranslatorInterface.php', - 'Laminas\\Validator\\UndisclosedPassword' => __DIR__ . '/..' . '/laminas/laminas-validator/src/UndisclosedPassword.php', - 'Laminas\\Validator\\Uri' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Uri.php', - 'Laminas\\Validator\\Uuid' => __DIR__ . '/..' . '/laminas/laminas-validator/src/Uuid.php', - 'Laminas\\Validator\\ValidatorChain' => __DIR__ . '/..' . '/laminas/laminas-validator/src/ValidatorChain.php', - 'Laminas\\Validator\\ValidatorInterface' => __DIR__ . '/..' . '/laminas/laminas-validator/src/ValidatorInterface.php', - 'Laminas\\Validator\\ValidatorPluginManager' => __DIR__ . '/..' . '/laminas/laminas-validator/src/ValidatorPluginManager.php', - 'Laminas\\Validator\\ValidatorPluginManagerAwareInterface' => __DIR__ . '/..' . '/laminas/laminas-validator/src/ValidatorPluginManagerAwareInterface.php', - 'Laminas\\Validator\\ValidatorPluginManagerFactory' => __DIR__ . '/..' . '/laminas/laminas-validator/src/ValidatorPluginManagerFactory.php', - 'Laminas\\Validator\\ValidatorProviderInterface' => __DIR__ . '/..' . '/laminas/laminas-validator/src/ValidatorProviderInterface.php', 'League\\OAuth2\\Client\\Exception\\HostedDomainException' => __DIR__ . '/..' . '/league/oauth2-google/src/Exception/HostedDomainException.php', 'League\\OAuth2\\Client\\Grant\\AbstractGrant' => __DIR__ . '/..' . '/league/oauth2-client/src/Grant/AbstractGrant.php', 'League\\OAuth2\\Client\\Grant\\AuthorizationCode' => __DIR__ . '/..' . '/league/oauth2-client/src/Grant/AuthorizationCode.php', @@ -1484,6 +1240,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'League\\OAuth2\\Client\\Token\\AccessToken' => __DIR__ . '/..' . '/league/oauth2-client/src/Token/AccessToken.php', 'League\\OAuth2\\Client\\Token\\AccessTokenInterface' => __DIR__ . '/..' . '/league/oauth2-client/src/Token/AccessTokenInterface.php', 'League\\OAuth2\\Client\\Token\\ResourceOwnerAccessTokenInterface' => __DIR__ . '/..' . '/league/oauth2-client/src/Token/ResourceOwnerAccessTokenInterface.php', + 'League\\OAuth2\\Client\\Token\\SettableRefreshTokenInterface' => __DIR__ . '/..' . '/league/oauth2-client/src/Token/SettableRefreshTokenInterface.php', 'League\\OAuth2\\Client\\Tool\\ArrayAccessorTrait' => __DIR__ . '/..' . '/league/oauth2-client/src/Tool/ArrayAccessorTrait.php', 'League\\OAuth2\\Client\\Tool\\BearerAuthorizationTrait' => __DIR__ . '/..' . '/league/oauth2-client/src/Tool/BearerAuthorizationTrait.php', 'League\\OAuth2\\Client\\Tool\\GuardedPropertyTrait' => __DIR__ . '/..' . '/league/oauth2-client/src/Tool/GuardedPropertyTrait.php', @@ -1572,10 +1329,13 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Pelago\\Emogrifier\\Css\\StyleRule' => __DIR__ . '/..' . '/pelago/emogrifier/src/Css/StyleRule.php', 'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/AbstractHtmlProcessor.php', 'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/CssToAttributeConverter.php', + 'Pelago\\Emogrifier\\HtmlProcessor\\CssVariableEvaluator' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/CssVariableEvaluator.php', 'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/HtmlNormalizer.php', 'Pelago\\Emogrifier\\HtmlProcessor\\HtmlPruner' => __DIR__ . '/..' . '/pelago/emogrifier/src/HtmlProcessor/HtmlPruner.php', 'Pelago\\Emogrifier\\Utilities\\ArrayIntersector' => __DIR__ . '/..' . '/pelago/emogrifier/src/Utilities/ArrayIntersector.php', 'Pelago\\Emogrifier\\Utilities\\CssConcatenator' => __DIR__ . '/..' . '/pelago/emogrifier/src/Utilities/CssConcatenator.php', + 'Pelago\\Emogrifier\\Utilities\\DeclarationBlockParser' => __DIR__ . '/..' . '/pelago/emogrifier/src/Utilities/DeclarationBlockParser.php', + 'Pelago\\Emogrifier\\Utilities\\Preg' => __DIR__ . '/..' . '/pelago/emogrifier/src/Utilities/Preg.php', 'PhpParser\\Builder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder.php', 'PhpParser\\BuilderFactory' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php', 'PhpParser\\BuilderHelpers' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php', @@ -1905,6 +1665,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'SQLUnionQuery' => __DIR__ . '/../..' . '/core/sqlunionquery.class.inc.php', 'SQLite3Exception' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php', 'SVGDOMSanitizer' => __DIR__ . '/../..' . '/core/htmlsanitizer.class.inc.php', + 'Sabberworm\\CSS\\CSSElement' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSElement.php', 'Sabberworm\\CSS\\CSSList\\AtRuleBlockList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSList/AtRuleBlockList.php', 'Sabberworm\\CSS\\CSSList\\CSSBlockList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSList/CSSBlockList.php', 'Sabberworm\\CSS\\CSSList\\CSSList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/CSSList/CSSList.php', @@ -1915,11 +1676,14 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Sabberworm\\CSS\\OutputFormat' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/OutputFormat.php', 'Sabberworm\\CSS\\OutputFormatter' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/OutputFormatter.php', 'Sabberworm\\CSS\\Parser' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parser.php', + 'Sabberworm\\CSS\\Parsing\\Anchor' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/Anchor.php', 'Sabberworm\\CSS\\Parsing\\OutputException' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/OutputException.php', 'Sabberworm\\CSS\\Parsing\\ParserState' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/ParserState.php', 'Sabberworm\\CSS\\Parsing\\SourceException' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/SourceException.php', 'Sabberworm\\CSS\\Parsing\\UnexpectedEOFException' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/UnexpectedEOFException.php', 'Sabberworm\\CSS\\Parsing\\UnexpectedTokenException' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Parsing/UnexpectedTokenException.php', + 'Sabberworm\\CSS\\Position\\Position' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Position/Position.php', + 'Sabberworm\\CSS\\Position\\Positionable' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Position/Positionable.php', 'Sabberworm\\CSS\\Property\\AtRule' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/AtRule.php', 'Sabberworm\\CSS\\Property\\CSSNamespace' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/CSSNamespace.php', 'Sabberworm\\CSS\\Property\\Charset' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Property/Charset.php', @@ -3045,6 +2809,128 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Component\\HttpKernel\\RebootableInterface' => __DIR__ . '/..' . '/symfony/http-kernel/RebootableInterface.php', 'Symfony\\Component\\HttpKernel\\TerminableInterface' => __DIR__ . '/..' . '/symfony/http-kernel/TerminableInterface.php', 'Symfony\\Component\\HttpKernel\\UriSigner' => __DIR__ . '/..' . '/symfony/http-kernel/UriSigner.php', + 'Symfony\\Component\\Mailer\\Command\\MailerTestCommand' => __DIR__ . '/..' . '/symfony/mailer/Command/MailerTestCommand.php', + 'Symfony\\Component\\Mailer\\DataCollector\\MessageDataCollector' => __DIR__ . '/..' . '/symfony/mailer/DataCollector/MessageDataCollector.php', + 'Symfony\\Component\\Mailer\\DelayedEnvelope' => __DIR__ . '/..' . '/symfony/mailer/DelayedEnvelope.php', + 'Symfony\\Component\\Mailer\\Envelope' => __DIR__ . '/..' . '/symfony/mailer/Envelope.php', + 'Symfony\\Component\\Mailer\\EventListener\\EnvelopeListener' => __DIR__ . '/..' . '/symfony/mailer/EventListener/EnvelopeListener.php', + 'Symfony\\Component\\Mailer\\EventListener\\MessageListener' => __DIR__ . '/..' . '/symfony/mailer/EventListener/MessageListener.php', + 'Symfony\\Component\\Mailer\\EventListener\\MessageLoggerListener' => __DIR__ . '/..' . '/symfony/mailer/EventListener/MessageLoggerListener.php', + 'Symfony\\Component\\Mailer\\EventListener\\MessengerTransportListener' => __DIR__ . '/..' . '/symfony/mailer/EventListener/MessengerTransportListener.php', + 'Symfony\\Component\\Mailer\\Event\\FailedMessageEvent' => __DIR__ . '/..' . '/symfony/mailer/Event/FailedMessageEvent.php', + 'Symfony\\Component\\Mailer\\Event\\MessageEvent' => __DIR__ . '/..' . '/symfony/mailer/Event/MessageEvent.php', + 'Symfony\\Component\\Mailer\\Event\\MessageEvents' => __DIR__ . '/..' . '/symfony/mailer/Event/MessageEvents.php', + 'Symfony\\Component\\Mailer\\Event\\SentMessageEvent' => __DIR__ . '/..' . '/symfony/mailer/Event/SentMessageEvent.php', + 'Symfony\\Component\\Mailer\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/mailer/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Mailer\\Exception\\HttpTransportException' => __DIR__ . '/..' . '/symfony/mailer/Exception/HttpTransportException.php', + 'Symfony\\Component\\Mailer\\Exception\\IncompleteDsnException' => __DIR__ . '/..' . '/symfony/mailer/Exception/IncompleteDsnException.php', + 'Symfony\\Component\\Mailer\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/mailer/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Mailer\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/mailer/Exception/LogicException.php', + 'Symfony\\Component\\Mailer\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/mailer/Exception/RuntimeException.php', + 'Symfony\\Component\\Mailer\\Exception\\TransportException' => __DIR__ . '/..' . '/symfony/mailer/Exception/TransportException.php', + 'Symfony\\Component\\Mailer\\Exception\\TransportExceptionInterface' => __DIR__ . '/..' . '/symfony/mailer/Exception/TransportExceptionInterface.php', + 'Symfony\\Component\\Mailer\\Exception\\UnexpectedResponseException' => __DIR__ . '/..' . '/symfony/mailer/Exception/UnexpectedResponseException.php', + 'Symfony\\Component\\Mailer\\Exception\\UnsupportedSchemeException' => __DIR__ . '/..' . '/symfony/mailer/Exception/UnsupportedSchemeException.php', + 'Symfony\\Component\\Mailer\\Header\\MetadataHeader' => __DIR__ . '/..' . '/symfony/mailer/Header/MetadataHeader.php', + 'Symfony\\Component\\Mailer\\Header\\TagHeader' => __DIR__ . '/..' . '/symfony/mailer/Header/TagHeader.php', + 'Symfony\\Component\\Mailer\\Mailer' => __DIR__ . '/..' . '/symfony/mailer/Mailer.php', + 'Symfony\\Component\\Mailer\\MailerInterface' => __DIR__ . '/..' . '/symfony/mailer/MailerInterface.php', + 'Symfony\\Component\\Mailer\\Messenger\\MessageHandler' => __DIR__ . '/..' . '/symfony/mailer/Messenger/MessageHandler.php', + 'Symfony\\Component\\Mailer\\Messenger\\SendEmailMessage' => __DIR__ . '/..' . '/symfony/mailer/Messenger/SendEmailMessage.php', + 'Symfony\\Component\\Mailer\\SentMessage' => __DIR__ . '/..' . '/symfony/mailer/SentMessage.php', + 'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailCount' => __DIR__ . '/..' . '/symfony/mailer/Test/Constraint/EmailCount.php', + 'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailIsQueued' => __DIR__ . '/..' . '/symfony/mailer/Test/Constraint/EmailIsQueued.php', + 'Symfony\\Component\\Mailer\\Test\\TransportFactoryTestCase' => __DIR__ . '/..' . '/symfony/mailer/Test/TransportFactoryTestCase.php', + 'Symfony\\Component\\Mailer\\Transport' => __DIR__ . '/..' . '/symfony/mailer/Transport.php', + 'Symfony\\Component\\Mailer\\Transport\\AbstractApiTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/AbstractApiTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\AbstractHttpTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/AbstractHttpTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\AbstractTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/AbstractTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\AbstractTransportFactory' => __DIR__ . '/..' . '/symfony/mailer/Transport/AbstractTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\Dsn' => __DIR__ . '/..' . '/symfony/mailer/Transport/Dsn.php', + 'Symfony\\Component\\Mailer\\Transport\\FailoverTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/FailoverTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\NativeTransportFactory' => __DIR__ . '/..' . '/symfony/mailer/Transport/NativeTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\NullTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/NullTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\NullTransportFactory' => __DIR__ . '/..' . '/symfony/mailer/Transport/NullTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\RoundRobinTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/RoundRobinTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\SendmailTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/SendmailTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\SendmailTransportFactory' => __DIR__ . '/..' . '/symfony/mailer/Transport/SendmailTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\AuthenticatorInterface' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\CramMd5Authenticator' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\LoginAuthenticator' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\PlainAuthenticator' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Auth\\XOAuth2Authenticator' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/EsmtpTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\EsmtpTransportFactory' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\SmtpTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/SmtpTransport.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Stream\\AbstractStream' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Stream\\ProcessStream' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php', + 'Symfony\\Component\\Mailer\\Transport\\Smtp\\Stream\\SocketStream' => __DIR__ . '/..' . '/symfony/mailer/Transport/Smtp/Stream/SocketStream.php', + 'Symfony\\Component\\Mailer\\Transport\\TransportFactoryInterface' => __DIR__ . '/..' . '/symfony/mailer/Transport/TransportFactoryInterface.php', + 'Symfony\\Component\\Mailer\\Transport\\TransportInterface' => __DIR__ . '/..' . '/symfony/mailer/Transport/TransportInterface.php', + 'Symfony\\Component\\Mailer\\Transport\\Transports' => __DIR__ . '/..' . '/symfony/mailer/Transport/Transports.php', + 'Symfony\\Component\\Mime\\Address' => __DIR__ . '/..' . '/symfony/mime/Address.php', + 'Symfony\\Component\\Mime\\BodyRendererInterface' => __DIR__ . '/..' . '/symfony/mime/BodyRendererInterface.php', + 'Symfony\\Component\\Mime\\CharacterStream' => __DIR__ . '/..' . '/symfony/mime/CharacterStream.php', + 'Symfony\\Component\\Mime\\Crypto\\DkimOptions' => __DIR__ . '/..' . '/symfony/mime/Crypto/DkimOptions.php', + 'Symfony\\Component\\Mime\\Crypto\\DkimSigner' => __DIR__ . '/..' . '/symfony/mime/Crypto/DkimSigner.php', + 'Symfony\\Component\\Mime\\Crypto\\SMime' => __DIR__ . '/..' . '/symfony/mime/Crypto/SMime.php', + 'Symfony\\Component\\Mime\\Crypto\\SMimeEncrypter' => __DIR__ . '/..' . '/symfony/mime/Crypto/SMimeEncrypter.php', + 'Symfony\\Component\\Mime\\Crypto\\SMimeSigner' => __DIR__ . '/..' . '/symfony/mime/Crypto/SMimeSigner.php', + 'Symfony\\Component\\Mime\\DependencyInjection\\AddMimeTypeGuesserPass' => __DIR__ . '/..' . '/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php', + 'Symfony\\Component\\Mime\\DraftEmail' => __DIR__ . '/..' . '/symfony/mime/DraftEmail.php', + 'Symfony\\Component\\Mime\\Email' => __DIR__ . '/..' . '/symfony/mime/Email.php', + 'Symfony\\Component\\Mime\\Encoder\\AddressEncoderInterface' => __DIR__ . '/..' . '/symfony/mime/Encoder/AddressEncoderInterface.php', + 'Symfony\\Component\\Mime\\Encoder\\Base64ContentEncoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/Base64ContentEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\Base64Encoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/Base64Encoder.php', + 'Symfony\\Component\\Mime\\Encoder\\Base64MimeHeaderEncoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/Base64MimeHeaderEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\ContentEncoderInterface' => __DIR__ . '/..' . '/symfony/mime/Encoder/ContentEncoderInterface.php', + 'Symfony\\Component\\Mime\\Encoder\\EightBitContentEncoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/EightBitContentEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\EncoderInterface' => __DIR__ . '/..' . '/symfony/mime/Encoder/EncoderInterface.php', + 'Symfony\\Component\\Mime\\Encoder\\IdnAddressEncoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/IdnAddressEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\MimeHeaderEncoderInterface' => __DIR__ . '/..' . '/symfony/mime/Encoder/MimeHeaderEncoderInterface.php', + 'Symfony\\Component\\Mime\\Encoder\\QpContentEncoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/QpContentEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\QpEncoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/QpEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\QpMimeHeaderEncoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/QpMimeHeaderEncoder.php', + 'Symfony\\Component\\Mime\\Encoder\\Rfc2231Encoder' => __DIR__ . '/..' . '/symfony/mime/Encoder/Rfc2231Encoder.php', + 'Symfony\\Component\\Mime\\Exception\\AddressEncoderException' => __DIR__ . '/..' . '/symfony/mime/Exception/AddressEncoderException.php', + 'Symfony\\Component\\Mime\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/mime/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Mime\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/mime/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Mime\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/mime/Exception/LogicException.php', + 'Symfony\\Component\\Mime\\Exception\\RfcComplianceException' => __DIR__ . '/..' . '/symfony/mime/Exception/RfcComplianceException.php', + 'Symfony\\Component\\Mime\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/mime/Exception/RuntimeException.php', + 'Symfony\\Component\\Mime\\FileBinaryMimeTypeGuesser' => __DIR__ . '/..' . '/symfony/mime/FileBinaryMimeTypeGuesser.php', + 'Symfony\\Component\\Mime\\FileinfoMimeTypeGuesser' => __DIR__ . '/..' . '/symfony/mime/FileinfoMimeTypeGuesser.php', + 'Symfony\\Component\\Mime\\Header\\AbstractHeader' => __DIR__ . '/..' . '/symfony/mime/Header/AbstractHeader.php', + 'Symfony\\Component\\Mime\\Header\\DateHeader' => __DIR__ . '/..' . '/symfony/mime/Header/DateHeader.php', + 'Symfony\\Component\\Mime\\Header\\HeaderInterface' => __DIR__ . '/..' . '/symfony/mime/Header/HeaderInterface.php', + 'Symfony\\Component\\Mime\\Header\\Headers' => __DIR__ . '/..' . '/symfony/mime/Header/Headers.php', + 'Symfony\\Component\\Mime\\Header\\IdentificationHeader' => __DIR__ . '/..' . '/symfony/mime/Header/IdentificationHeader.php', + 'Symfony\\Component\\Mime\\Header\\MailboxHeader' => __DIR__ . '/..' . '/symfony/mime/Header/MailboxHeader.php', + 'Symfony\\Component\\Mime\\Header\\MailboxListHeader' => __DIR__ . '/..' . '/symfony/mime/Header/MailboxListHeader.php', + 'Symfony\\Component\\Mime\\Header\\ParameterizedHeader' => __DIR__ . '/..' . '/symfony/mime/Header/ParameterizedHeader.php', + 'Symfony\\Component\\Mime\\Header\\PathHeader' => __DIR__ . '/..' . '/symfony/mime/Header/PathHeader.php', + 'Symfony\\Component\\Mime\\Header\\UnstructuredHeader' => __DIR__ . '/..' . '/symfony/mime/Header/UnstructuredHeader.php', + 'Symfony\\Component\\Mime\\HtmlToTextConverter\\DefaultHtmlToTextConverter' => __DIR__ . '/..' . '/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php', + 'Symfony\\Component\\Mime\\HtmlToTextConverter\\HtmlToTextConverterInterface' => __DIR__ . '/..' . '/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php', + 'Symfony\\Component\\Mime\\HtmlToTextConverter\\LeagueHtmlToMarkdownConverter' => __DIR__ . '/..' . '/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php', + 'Symfony\\Component\\Mime\\Message' => __DIR__ . '/..' . '/symfony/mime/Message.php', + 'Symfony\\Component\\Mime\\MessageConverter' => __DIR__ . '/..' . '/symfony/mime/MessageConverter.php', + 'Symfony\\Component\\Mime\\MimeTypeGuesserInterface' => __DIR__ . '/..' . '/symfony/mime/MimeTypeGuesserInterface.php', + 'Symfony\\Component\\Mime\\MimeTypes' => __DIR__ . '/..' . '/symfony/mime/MimeTypes.php', + 'Symfony\\Component\\Mime\\MimeTypesInterface' => __DIR__ . '/..' . '/symfony/mime/MimeTypesInterface.php', + 'Symfony\\Component\\Mime\\Part\\AbstractMultipartPart' => __DIR__ . '/..' . '/symfony/mime/Part/AbstractMultipartPart.php', + 'Symfony\\Component\\Mime\\Part\\AbstractPart' => __DIR__ . '/..' . '/symfony/mime/Part/AbstractPart.php', + 'Symfony\\Component\\Mime\\Part\\DataPart' => __DIR__ . '/..' . '/symfony/mime/Part/DataPart.php', + 'Symfony\\Component\\Mime\\Part\\File' => __DIR__ . '/..' . '/symfony/mime/Part/File.php', + 'Symfony\\Component\\Mime\\Part\\MessagePart' => __DIR__ . '/..' . '/symfony/mime/Part/MessagePart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\AlternativePart' => __DIR__ . '/..' . '/symfony/mime/Part/Multipart/AlternativePart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\DigestPart' => __DIR__ . '/..' . '/symfony/mime/Part/Multipart/DigestPart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\FormDataPart' => __DIR__ . '/..' . '/symfony/mime/Part/Multipart/FormDataPart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\MixedPart' => __DIR__ . '/..' . '/symfony/mime/Part/Multipart/MixedPart.php', + 'Symfony\\Component\\Mime\\Part\\Multipart\\RelatedPart' => __DIR__ . '/..' . '/symfony/mime/Part/Multipart/RelatedPart.php', + 'Symfony\\Component\\Mime\\Part\\SMimePart' => __DIR__ . '/..' . '/symfony/mime/Part/SMimePart.php', + 'Symfony\\Component\\Mime\\Part\\TextPart' => __DIR__ . '/..' . '/symfony/mime/Part/TextPart.php', + 'Symfony\\Component\\Mime\\RawMessage' => __DIR__ . '/..' . '/symfony/mime/RawMessage.php', 'Symfony\\Component\\Routing\\Alias' => __DIR__ . '/..' . '/symfony/routing/Alias.php', 'Symfony\\Component\\Routing\\Annotation\\Route' => __DIR__ . '/..' . '/symfony/routing/Annotation/Route.php', 'Symfony\\Component\\Routing\\Attribute\\Route' => __DIR__ . '/..' . '/symfony/routing/Attribute/Route.php', @@ -3275,7 +3161,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Polyfill\\Intl\\Idn\\Resources\\unidata\\Regex' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/Resources/unidata/Regex.php', 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Normalizer.php', 'Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php', - 'Symfony\\Polyfill\\Php72\\Php72' => __DIR__ . '/..' . '/symfony/polyfill-php72/Php72.php', 'Symfony\\Polyfill\\Php80\\Php80' => __DIR__ . '/..' . '/symfony/polyfill-php80/Php80.php', 'Symfony\\Polyfill\\Php80\\PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/PhpToken.php', 'Symfony\\Polyfill\\Php83\\Php83' => __DIR__ . '/..' . '/symfony/polyfill-php83/Php83.php', @@ -3602,9 +3487,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'VariableExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php', 'VariableOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php', 'WebPageMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php', - 'Webmozart\\Assert\\Assert' => __DIR__ . '/..' . '/webmozart/assert/src/Assert.php', - 'Webmozart\\Assert\\InvalidArgumentException' => __DIR__ . '/..' . '/webmozart/assert/src/InvalidArgumentException.php', - 'Webmozart\\Assert\\Mixin' => __DIR__ . '/..' . '/webmozart/assert/src/Mixin.php', 'WeeklyRotatingLogFileNameBuilder' => __DIR__ . '/../..' . '/core/log.class.inc.php', 'WizardHelper' => __DIR__ . '/../..' . '/application/wizardhelper.class.inc.php', 'XLSXWriter' => __DIR__ . '/../..' . '/application/xlsxwriter.class.php', diff --git a/lib/composer/installed.json b/lib/composer/installed.json index c14df0992..7b246762b 100644 --- a/lib/composer/installed.json +++ b/lib/composer/installed.json @@ -74,6 +74,156 @@ }, "install-path": "../apereo/phpcas" }, + { + "name": "doctrine/lexer", + "version": "3.0.1", + "version_normalized": "3.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "time": "2024-02-05T11:56:58+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "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": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "install-path": "../doctrine/lexer" + }, + { + "name": "egulias/email-validator", + "version": "4.0.4", + "version_normalized": "4.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "time": "2025-03-06T22:45:56+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "install-path": "../egulias/email-validator" + }, { "name": "firebase/php-jwt", "version": "v6.10.0", @@ -474,452 +624,6 @@ ], "install-path": "../guzzlehttp/psr7" }, - { - "name": "laminas/laminas-loader", - "version": "2.10.0", - "version_normalized": "2.10.0.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-loader.git", - "reference": "e6fe952304ef40ce45cd814751ab35d42afdad12" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/e6fe952304ef40ce45cd814751ab35d42afdad12", - "reference": "e6fe952304ef40ce45cd814751ab35d42afdad12", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-loader": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "~9.5.25" - }, - "time": "2023-10-18T09:58:51+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Laminas\\Loader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Autoloading and plugin loading strategies", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "loader" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-loader/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-loader/issues", - "rss": "https://github.com/laminas/laminas-loader/releases.atom", - "source": "https://github.com/laminas/laminas-loader" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "install-path": "../laminas/laminas-loader" - }, - { - "name": "laminas/laminas-mail", - "version": "2.22.0", - "version_normalized": "2.22.0.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-mail.git", - "reference": "1d307ff65328c00117c6d90ba0084fdd0fc2bd5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-mail/zipball/1d307ff65328c00117c6d90ba0084fdd0fc2bd5c", - "reference": "1d307ff65328c00117c6d90ba0084fdd0fc2bd5c", - "shasum": "" - }, - "require": { - "ext-iconv": "*", - "laminas/laminas-loader": "^2.8.0", - "laminas/laminas-mime": "^2.10.0", - "laminas/laminas-stdlib": "^3.11.0", - "laminas/laminas-validator": "^2.23.0", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "symfony/polyfill-intl-idn": "^1.26.0", - "symfony/polyfill-mbstring": "^1.16.0", - "webmozart/assert": "^1.11.0" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-crypt": "^3.9.0", - "laminas/laminas-db": "^2.16", - "laminas/laminas-servicemanager": "^3.20", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.4", - "symfony/process": "^6.0.11", - "vimeo/psalm": "^5.1" - }, - "suggest": { - "laminas/laminas-crypt": "^3.8 Crammd5 support in SMTP Auth", - "laminas/laminas-servicemanager": "^3.16 when using SMTP to deliver messages" - }, - "time": "2023-01-18T08:33:48+00:00", - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Mail", - "config-provider": "Laminas\\Mail\\ConfigProvider" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Laminas\\Mail\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "mail" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-mail/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-mail/issues", - "rss": "https://github.com/laminas/laminas-mail/releases.atom", - "source": "https://github.com/laminas/laminas-mail" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "install-path": "../laminas/laminas-mail" - }, - { - "name": "laminas/laminas-mime", - "version": "2.12.0", - "version_normalized": "2.12.0.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-mime.git", - "reference": "08cc544778829b7d68d27a097885bd6e7130135e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-mime/zipball/08cc544778829b7d68d27a097885bd6e7130135e", - "reference": "08cc544778829b7d68d27a097885bd6e7130135e", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^2.7 || ^3.0", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-mime": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-mail": "^2.19.0", - "phpunit/phpunit": "~9.5.25" - }, - "suggest": { - "laminas/laminas-mail": "Laminas\\Mail component" - }, - "time": "2023-11-02T16:47:19+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Laminas\\Mime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Create and parse MIME messages and parts", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "mime" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-mime/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-mime/issues", - "rss": "https://github.com/laminas/laminas-mime/releases.atom", - "source": "https://github.com/laminas/laminas-mime" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "install-path": "../laminas/laminas-mime" - }, - { - "name": "laminas/laminas-servicemanager", - "version": "3.22.1", - "version_normalized": "3.22.1.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "de98d297d4743956a0558a6d71616979ff779328" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/de98d297d4743956a0558a6d71616979ff779328", - "reference": "de98d297d4743956a0558a6d71616979ff779328", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.17", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "psr/container": "^1.0" - }, - "conflict": { - "ext-psr": "*", - "laminas/laminas-code": "<4.10.0", - "zendframework/zend-code": "<3.3.1", - "zendframework/zend-servicemanager": "*" - }, - "provide": { - "psr/container-implementation": "^1.0" - }, - "replace": { - "container-interop/container-interop": "^1.2.0" - }, - "require-dev": { - "composer/package-versions-deprecated": "^1.11.99.5", - "friendsofphp/proxy-manager-lts": "^1.0.14", - "laminas/laminas-code": "^4.10.0", - "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-container-config-test": "^0.8", - "mikey179/vfsstream": "^1.6.11", - "phpbench/phpbench": "^1.2.9", - "phpunit/phpunit": "^10.4", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.8.0" - }, - "suggest": { - "friendsofphp/proxy-manager-lts": "ProxyManager ^2.1.1 to handle lazy initialization of services" - }, - "time": "2023-10-24T11:19:47+00:00", - "bin": [ - "bin/generate-deps-for-config-factory", - "bin/generate-factory-for-class" - ], - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Laminas\\ServiceManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Factory-Driven Dependency Injection Container", - "homepage": "https://laminas.dev", - "keywords": [ - "PSR-11", - "dependency-injection", - "di", - "dic", - "laminas", - "service-manager", - "servicemanager" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-servicemanager/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-servicemanager/issues", - "rss": "https://github.com/laminas/laminas-servicemanager/releases.atom", - "source": "https://github.com/laminas/laminas-servicemanager" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "install-path": "../laminas/laminas-servicemanager" - }, - { - "name": "laminas/laminas-stdlib", - "version": "3.19.0", - "version_normalized": "3.19.0.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "6a192dd0882b514e45506f533b833b623b78fff3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/6a192dd0882b514e45506f533b833b623b78fff3", - "reference": "6a192dd0882b514e45506f533b833b623b78fff3", - "shasum": "" - }, - "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-stdlib": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.5", - "phpbench/phpbench": "^1.2.15", - "phpunit/phpunit": "^10.5.8", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.20.0" - }, - "time": "2024-01-19T12:39:49+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Laminas\\Stdlib\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "SPL extensions, array utilities, error handlers, and more", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "stdlib" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-stdlib/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-stdlib/issues", - "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", - "source": "https://github.com/laminas/laminas-stdlib" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "install-path": "../laminas/laminas-stdlib" - }, - { - "name": "laminas/laminas-validator", - "version": "2.27.0", - "version_normalized": "2.27.0.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-validator.git", - "reference": "451f5e24574a99b86e8e22f0431ccfc6d5c7318b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/451f5e24574a99b86e8e22f0431ccfc6d5c7318b", - "reference": "451f5e24574a99b86e8e22f0431ccfc6d5c7318b", - "shasum": "" - }, - "require": { - "laminas/laminas-servicemanager": "^3.12.0", - "laminas/laminas-stdlib": "^3.13", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-validator": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "laminas/laminas-db": "^2.15.0", - "laminas/laminas-filter": "^2.23.0", - "laminas/laminas-http": "^2.17.0", - "laminas/laminas-i18n": "^2.19", - "laminas/laminas-session": "^2.13.0", - "laminas/laminas-uri": "^2.10.0", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.18.0", - "psr/http-client": "^1.0.1", - "psr/http-factory": "^1.0.1", - "psr/http-message": "^1.0.1", - "vimeo/psalm": "^4.28" - }, - "suggest": { - "laminas/laminas-db": "Laminas\\Db component, required by the (No)RecordExists validator", - "laminas/laminas-filter": "Laminas\\Filter component, required by the Digits validator", - "laminas/laminas-i18n": "Laminas\\I18n component to allow translation of validation error messages", - "laminas/laminas-i18n-resources": "Translations of validator messages", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", - "laminas/laminas-session": "Laminas\\Session component, ^2.8; required by the Csrf validator", - "laminas/laminas-uri": "Laminas\\Uri component, required by the Uri and Sitemap\\Loc validators", - "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators" - }, - "time": "2022-11-12T21:00:53+00:00", - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Validator", - "config-provider": "Laminas\\Validator\\ConfigProvider" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Laminas\\Validator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "validator" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-validator/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-validator/issues", - "rss": "https://github.com/laminas/laminas-validator/releases.atom", - "source": "https://github.com/laminas/laminas-validator" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "install-path": "../laminas/laminas-validator" - }, { "name": "league/oauth2-client", "version": "2.7.0", @@ -2700,31 +2404,31 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", - "version_normalized": "3.4.0.0", + "version": "v3.6.0", + "version_normalized": "3.6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { "php": ">=8.1" }, - "time": "2023-05-23T14:45:45+00:00", + "time": "2024-09-25T14:21:43+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "installation-source": "dist", @@ -2750,7 +2454,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { @@ -2925,17 +2629,17 @@ }, { "name": "symfony/event-dispatcher", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.25", + "version_normalized": "6.4.25.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "e95216850555cd55e71b857eb9d6c2674124603a" + "reference": "b0cf3162020603587363f0551cd3be43958611ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e95216850555cd55e71b857eb9d6c2674124603a", - "reference": "e95216850555cd55e71b857eb9d6c2674124603a", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b0cf3162020603587363f0551cd3be43958611ff", + "reference": "b0cf3162020603587363f0551cd3be43958611ff", "shasum": "" }, "require": { @@ -2960,7 +2664,7 @@ "symfony/service-contracts": "^2.5|^3", "symfony/stopwatch": "^5.4|^6.0|^7.0" }, - "time": "2023-12-27T22:16:42+00:00", + "time": "2025-08-13T09:41:44+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2988,7 +2692,7 @@ "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": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.25" }, "funding": [ { @@ -2999,6 +2703,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -3008,32 +2716,32 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.0", - "version_normalized": "3.4.0.0", + "version": "v3.6.0", + "version_normalized": "3.6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", "shasum": "" }, "require": { "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "time": "2023-05-23T14:45:45+00:00", + "time": "2024-09-25T14:21:43+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "installation-source": "dist", @@ -3067,7 +2775,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" }, "funding": [ { @@ -3565,6 +3273,185 @@ ], "install-path": "../symfony/http-kernel" }, + { + "name": "symfony/mailer", + "version": "v6.4.25", + "version_normalized": "6.4.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/628b43b45a3e6b15c8a633fb22df547ed9b492a2", + "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.1", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/messenger": "<6.2", + "symfony/mime": "<6.2", + "symfony/twig-bridge": "<6.2.1" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.2|^7.0", + "symfony/twig-bridge": "^6.2|^7.0" + }, + "time": "2025-08-13T09:41:44+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.4.25" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/mailer" + }, + { + "name": "symfony/mime", + "version": "v6.4.24", + "version_normalized": "6.4.24.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/664d5e844a2de5e11c8255d0aef6bc15a9660ac7", + "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "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": "<5.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "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": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "time": "2025-07-15T12:02:45+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.4.24" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/mime" + }, { "name": "symfony/polyfill-ctype", "version": "v1.28.0", @@ -3736,36 +3623,32 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2023-01-26T09:30:37+00:00", + "time": "2024-09-10T14:38:51+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -3806,7 +3689,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" }, "funding": [ { @@ -3817,6 +3700,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -3826,34 +3713,31 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2023-01-26T09:26:14+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -3893,7 +3777,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" }, "funding": [ { @@ -3904,6 +3788,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -3913,21 +3801,22 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -3935,15 +3824,12 @@ "suggest": { "ext-mbstring": "For best performance" }, - "time": "2023-07-28T09:04:16+00:00", + "time": "2024-12-23T08:48:59+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -3979,7 +3865,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -3990,6 +3876,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -3997,112 +3887,30 @@ ], "install-path": "../symfony/polyfill-mbstring" }, - { - "name": "symfony/polyfill-php72", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2023-01-26T09:26:14+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0" - }, - "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" - } - ], - "install-path": "../symfony/polyfill-php72" - }, { "name": "symfony/polyfill-php80", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "time": "2023-01-26T09:26:14+00:00", + "time": "2025-01-02T08:10:11+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -4144,7 +3952,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" }, "funding": [ { @@ -4155,6 +3963,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -4419,35 +4231,36 @@ }, { "name": "symfony/service-contracts", - "version": "v3.4.1", - "version_normalized": "3.4.1.0", + "version": "v3.6.0", + "version_normalized": "3.6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "time": "2023-12-26T14:02:43+00:00", + "time": "2025-04-25T09:37:31+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "installation-source": "dist", @@ -4484,7 +4297,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" }, "funding": [ { @@ -5480,67 +5293,6 @@ } ], "install-path": "../twig/twig" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "version_normalized": "1.11.0.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" - }, - "time": "2022-06-03T18:03:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "installation-source": "dist", - "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" - }, - "install-path": "../webmozart/assert" } ], "dev": true, diff --git a/lib/composer/installed.php b/lib/composer/installed.php index 928d15233..1a90038dd 100644 --- a/lib/composer/installed.php +++ b/lib/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'combodo/itop', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => '7a3e770c00619e93628235b12fe820f3f1ce6c77', + 'reference' => 'c88ba664db4ec5622838a0ee00768e3bc3381d4e', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -22,17 +22,29 @@ 'combodo/itop' => array( 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', - 'reference' => '7a3e770c00619e93628235b12fe820f3f1ce6c77', + 'reference' => 'c88ba664db4ec5622838a0ee00768e3bc3381d4e', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), - 'container-interop/container-interop' => array( + 'doctrine/lexer' => array( + 'pretty_version' => '3.0.1', + 'version' => '3.0.1.0', + 'reference' => '31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd', + 'type' => 'library', + 'install_path' => __DIR__ . '/../doctrine/lexer', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'egulias/email-validator' => array( + 'pretty_version' => '4.0.4', + 'version' => '4.0.4.0', + 'reference' => 'd42c8731f0624ad6bdc8d3e5e9a4524f68801cfa', + 'type' => 'library', + 'install_path' => __DIR__ . '/../egulias/email-validator', + 'aliases' => array(), 'dev_requirement' => false, - 'replaced' => array( - 0 => '^1.2.0', - ), ), 'firebase/php-jwt' => array( 'pretty_version' => 'v6.10.0', @@ -70,60 +82,6 @@ 'aliases' => array(), 'dev_requirement' => false, ), - 'laminas/laminas-loader' => array( - 'pretty_version' => '2.10.0', - 'version' => '2.10.0.0', - 'reference' => 'e6fe952304ef40ce45cd814751ab35d42afdad12', - 'type' => 'library', - 'install_path' => __DIR__ . '/../laminas/laminas-loader', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'laminas/laminas-mail' => array( - 'pretty_version' => '2.22.0', - 'version' => '2.22.0.0', - 'reference' => '1d307ff65328c00117c6d90ba0084fdd0fc2bd5c', - 'type' => 'library', - 'install_path' => __DIR__ . '/../laminas/laminas-mail', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'laminas/laminas-mime' => array( - 'pretty_version' => '2.12.0', - 'version' => '2.12.0.0', - 'reference' => '08cc544778829b7d68d27a097885bd6e7130135e', - 'type' => 'library', - 'install_path' => __DIR__ . '/../laminas/laminas-mime', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'laminas/laminas-servicemanager' => array( - 'pretty_version' => '3.22.1', - 'version' => '3.22.1.0', - 'reference' => 'de98d297d4743956a0558a6d71616979ff779328', - 'type' => 'library', - 'install_path' => __DIR__ . '/../laminas/laminas-servicemanager', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'laminas/laminas-stdlib' => array( - 'pretty_version' => '3.19.0', - 'version' => '3.19.0.0', - 'reference' => '6a192dd0882b514e45506f533b833b623b78fff3', - 'type' => 'library', - 'install_path' => __DIR__ . '/../laminas/laminas-stdlib', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'laminas/laminas-validator' => array( - 'pretty_version' => '2.27.0', - 'version' => '2.27.0.0', - 'reference' => '451f5e24574a99b86e8e22f0431ccfc6d5c7318b', - 'type' => 'library', - 'install_path' => __DIR__ . '/../laminas/laminas-validator', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'league/oauth2-client' => array( 'pretty_version' => '2.7.0', 'version' => '2.7.0.0', @@ -233,7 +191,6 @@ 'dev_requirement' => false, 'provided' => array( 0 => '1.1|2.0', - 1 => '^1.0', ), ), 'psr/event-dispatcher' => array( @@ -429,9 +386,9 @@ 'dev_requirement' => false, ), 'symfony/deprecation-contracts' => array( - 'pretty_version' => 'v3.4.0', - 'version' => '3.4.0.0', - 'reference' => '7c3aff79d10325257a001fcf92d991f24fc967cf', + 'pretty_version' => 'v3.6.0', + 'version' => '3.6.0.0', + 'reference' => '63afe740e99a13ba87ec199bb07bbdee937a5b62', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), @@ -456,18 +413,18 @@ 'dev_requirement' => false, ), 'symfony/event-dispatcher' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => 'e95216850555cd55e71b857eb9d6c2674124603a', + 'pretty_version' => 'v6.4.25', + 'version' => '6.4.25.0', + 'reference' => 'b0cf3162020603587363f0551cd3be43958611ff', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/event-dispatcher', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/event-dispatcher-contracts' => array( - 'pretty_version' => 'v3.4.0', - 'version' => '3.4.0.0', - 'reference' => 'a76aed96a42d2b521153fb382d418e30d18b59df', + 'pretty_version' => 'v3.6.0', + 'version' => '3.6.0.0', + 'reference' => '59eb412e93815df44f05f342958efa9f46b1e586', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts', 'aliases' => array(), @@ -524,6 +481,24 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'symfony/mailer' => array( + 'pretty_version' => 'v6.4.25', + 'version' => '6.4.25.0', + 'reference' => '628b43b45a3e6b15c8a633fb22df547ed9b492a2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/mailer', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/mime' => array( + 'pretty_version' => 'v6.4.24', + 'version' => '6.4.24.0', + 'reference' => '664d5e844a2de5e11c8255d0aef6bc15a9660ac7', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/mime', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'symfony/polyfill-ctype' => array( 'pretty_version' => 'v1.28.0', 'version' => '1.28.0.0', @@ -543,45 +518,36 @@ 'dev_requirement' => false, ), 'symfony/polyfill-intl-idn' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => 'ecaafce9f77234a6a449d29e49267ba10499116d', + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '9614ac4d8061dc257ecc64cba1b140873dce8ad3', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-intl-normalizer' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92', + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '3833d7255cc303546435cb650316bff708a1c75c', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-mbstring' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => '42292d99c55abe617799667f454222c54c60e229', + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '6d857f4d76bd4b343eac26d6b539585d2bc56493', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'dev_requirement' => false, ), - 'symfony/polyfill-php72' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => '70f4aebd92afca2f865444d30a4d2151c13c3179', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-php72', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'symfony/polyfill-php80' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '0cc9dd0f17f61d8131e7df6b84bd344899fe2608', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), @@ -615,9 +581,9 @@ 'dev_requirement' => false, ), 'symfony/service-contracts' => array( - 'pretty_version' => 'v3.4.1', - 'version' => '3.4.1.0', - 'reference' => 'fe07cbc8d837f60caf7018068e350cc5163681a0', + 'pretty_version' => 'v3.6.0', + 'version' => '3.6.0.0', + 'reference' => 'f021b05a130d35510bd6b25fe9053c2a8a15d5d4', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/service-contracts', 'aliases' => array(), @@ -737,14 +703,5 @@ 'aliases' => array(), 'dev_requirement' => false, ), - 'webmozart/assert' => array( - 'pretty_version' => '1.11.0', - 'version' => '1.11.0.0', - 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991', - 'type' => 'library', - 'install_path' => __DIR__ . '/../webmozart/assert', - 'aliases' => array(), - 'dev_requirement' => false, - ), ), ); diff --git a/lib/webmozart/assert/LICENSE b/lib/doctrine/lexer/LICENSE similarity index 52% rename from lib/webmozart/assert/LICENSE rename to lib/doctrine/lexer/LICENSE index 9e2e3075e..e8fdec4af 100644 --- a/lib/webmozart/assert/LICENSE +++ b/lib/doctrine/lexer/LICENSE @@ -1,20 +1,19 @@ -The MIT License (MIT) - -Copyright (c) 2014 Bernhard Schussek +Copyright (c) 2006-2018 Doctrine Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/doctrine/lexer/README.md b/lib/doctrine/lexer/README.md new file mode 100644 index 000000000..784f2a271 --- /dev/null +++ b/lib/doctrine/lexer/README.md @@ -0,0 +1,9 @@ +# Doctrine Lexer + +[![Build Status](https://github.com/doctrine/lexer/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/lexer/actions) + +Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers. + +This lexer is used in Doctrine Annotations and in Doctrine ORM (DQL). + +https://www.doctrine-project.org/projects/lexer.html diff --git a/lib/doctrine/lexer/UPGRADE.md b/lib/doctrine/lexer/UPGRADE.md new file mode 100644 index 000000000..1933fcb2e --- /dev/null +++ b/lib/doctrine/lexer/UPGRADE.md @@ -0,0 +1,22 @@ +Note about upgrading: Doctrine uses static and runtime mechanisms to raise +awareness about deprecated code. + +- Use of `@deprecated` docblock that is detected by IDEs (like PHPStorm) or + Static Analysis tools (like Psalm, phpstan) +- Use of our low-overhead runtime deprecation API, details: + https://github.com/doctrine/deprecations/ + +# Upgrade to 3.0.0 + +`Doctrine\Common\Lexer\Token` no longer implements `ArrayAccess`. +Parameter type declarations have been added to +`Doctrine\Common\Lexer\AbstractLexer` and `Doctrine\Common\Lexer\Token`. +You should add both parameter type declarations and return type declarations to +your lexers, based on the `@return` phpdoc. + +# Upgrade to 2.0.0 + +`AbstractLexer::glimpse()` and `AbstractLexer::peek()` now return +instances of `Doctrine\Common\Lexer\Token`, which is an array-like class +Using it as an array is deprecated in favor of using properties of that class. +Using `count()` on it is deprecated with no replacement. diff --git a/lib/doctrine/lexer/composer.json b/lib/doctrine/lexer/composer.json new file mode 100644 index 000000000..995dafa0d --- /dev/null +++ b/lib/doctrine/lexer/composer.json @@ -0,0 +1,55 @@ +{ + "name": "doctrine/lexer", + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "license": "MIT", + "type": "library", + "keywords": [ + "php", + "parser", + "lexer", + "annotations", + "docblock" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Doctrine\\Tests\\Common\\Lexer\\": "tests" + } + }, + "config": { + "allow-plugins": { + "composer/package-versions-deprecated": true, + "dealerdirect/phpcodesniffer-composer-installer": true + }, + "sort-packages": true + } +} diff --git a/lib/doctrine/lexer/src/AbstractLexer.php b/lib/doctrine/lexer/src/AbstractLexer.php new file mode 100644 index 000000000..2436885e4 --- /dev/null +++ b/lib/doctrine/lexer/src/AbstractLexer.php @@ -0,0 +1,328 @@ +> + */ + private array $tokens = []; + + /** + * Current lexer position in input string. + */ + private int $position = 0; + + /** + * Current peek of current lexer position. + */ + private int $peek = 0; + + /** + * The next token in the input. + * + * @var Token|null + */ + public Token|null $lookahead; + + /** + * The last matched/seen token. + * + * @var Token|null + */ + public Token|null $token; + + /** + * Composed regex for input parsing. + * + * @var non-empty-string|null + */ + private string|null $regex = null; + + /** + * Sets the input data to be tokenized. + * + * The Lexer is immediately reset and the new input tokenized. + * Any unprocessed tokens from any previous input are lost. + * + * @param string $input The input to be tokenized. + * + * @return void + */ + public function setInput(string $input) + { + $this->input = $input; + $this->tokens = []; + + $this->reset(); + $this->scan($input); + } + + /** + * Resets the lexer. + * + * @return void + */ + public function reset() + { + $this->lookahead = null; + $this->token = null; + $this->peek = 0; + $this->position = 0; + } + + /** + * Resets the peek pointer to 0. + * + * @return void + */ + public function resetPeek() + { + $this->peek = 0; + } + + /** + * Resets the lexer position on the input to the given position. + * + * @param int $position Position to place the lexical scanner. + * + * @return void + */ + public function resetPosition(int $position = 0) + { + $this->position = $position; + } + + /** + * Retrieve the original lexer's input until a given position. + * + * @return string + */ + public function getInputUntilPosition(int $position) + { + return substr($this->input, 0, $position); + } + + /** + * Checks whether a given token matches the current lookahead. + * + * @param T $type + * + * @return bool + * + * @psalm-assert-if-true !=null $this->lookahead + */ + public function isNextToken(int|string|UnitEnum $type) + { + return $this->lookahead !== null && $this->lookahead->isA($type); + } + + /** + * Checks whether any of the given tokens matches the current lookahead. + * + * @param list $types + * + * @return bool + * + * @psalm-assert-if-true !=null $this->lookahead + */ + public function isNextTokenAny(array $types) + { + return $this->lookahead !== null && $this->lookahead->isA(...$types); + } + + /** + * Moves to the next token in the input string. + * + * @return bool + * + * @psalm-assert-if-true !null $this->lookahead + */ + public function moveNext() + { + $this->peek = 0; + $this->token = $this->lookahead; + $this->lookahead = isset($this->tokens[$this->position]) + ? $this->tokens[$this->position++] : null; + + return $this->lookahead !== null; + } + + /** + * Tells the lexer to skip input tokens until it sees a token with the given value. + * + * @param T $type The token type to skip until. + * + * @return void + */ + public function skipUntil(int|string|UnitEnum $type) + { + while ($this->lookahead !== null && ! $this->lookahead->isA($type)) { + $this->moveNext(); + } + } + + /** + * Checks if given value is identical to the given token. + * + * @return bool + */ + public function isA(string $value, int|string|UnitEnum $token) + { + return $this->getType($value) === $token; + } + + /** + * Moves the lookahead token forward. + * + * @return Token|null The next token or NULL if there are no more tokens ahead. + */ + public function peek() + { + if (isset($this->tokens[$this->position + $this->peek])) { + return $this->tokens[$this->position + $this->peek++]; + } + + return null; + } + + /** + * Peeks at the next token, returns it and immediately resets the peek. + * + * @return Token|null The next token or NULL if there are no more tokens ahead. + */ + public function glimpse() + { + $peek = $this->peek(); + $this->peek = 0; + + return $peek; + } + + /** + * Scans the input string for tokens. + * + * @param string $input A query string. + * + * @return void + */ + protected function scan(string $input) + { + if (! isset($this->regex)) { + $this->regex = sprintf( + '/(%s)|%s/%s', + implode(')|(', $this->getCatchablePatterns()), + implode('|', $this->getNonCatchablePatterns()), + $this->getModifiers(), + ); + } + + $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE; + $matches = preg_split($this->regex, $input, -1, $flags); + + if ($matches === false) { + // Work around https://bugs.php.net/78122 + $matches = [[$input, 0]]; + } + + foreach ($matches as $match) { + // Must remain before 'value' assignment since it can change content + $firstMatch = $match[0]; + $type = $this->getType($firstMatch); + + $this->tokens[] = new Token( + $firstMatch, + $type, + $match[1], + ); + } + } + + /** + * Gets the literal for a given token. + * + * @param T $token + * + * @return int|string + */ + public function getLiteral(int|string|UnitEnum $token) + { + if ($token instanceof UnitEnum) { + return $token::class . '::' . $token->name; + } + + $className = static::class; + + $reflClass = new ReflectionClass($className); + $constants = $reflClass->getConstants(); + + foreach ($constants as $name => $value) { + if ($value === $token) { + return $className . '::' . $name; + } + } + + return $token; + } + + /** + * Regex modifiers + * + * @return string + */ + protected function getModifiers() + { + return 'iu'; + } + + /** + * Lexical catchable patterns. + * + * @return string[] + */ + abstract protected function getCatchablePatterns(); + + /** + * Lexical non-catchable patterns. + * + * @return string[] + */ + abstract protected function getNonCatchablePatterns(); + + /** + * Retrieve token type. Also processes the token value if necessary. + * + * @return T|null + * + * @param-out V $value + */ + abstract protected function getType(string &$value); +} diff --git a/lib/doctrine/lexer/src/Token.php b/lib/doctrine/lexer/src/Token.php new file mode 100644 index 000000000..b6df69465 --- /dev/null +++ b/lib/doctrine/lexer/src/Token.php @@ -0,0 +1,56 @@ +value = $value; + $this->type = $type; + $this->position = $position; + } + + /** @param T ...$types */ + public function isA(...$types): bool + { + return in_array($this->type, $types, true); + } +} diff --git a/lib/egulias/email-validator/CONTRIBUTING.md b/lib/egulias/email-validator/CONTRIBUTING.md new file mode 100644 index 000000000..907bc2c9b --- /dev/null +++ b/lib/egulias/email-validator/CONTRIBUTING.md @@ -0,0 +1,153 @@ +# Contributing + +When contributing to this repository make sure to follow the Pull request process below. +Reduce to the minimum 3rd party dependencies. + +Please note we have a [code of conduct](#Code of Conduct), please follow it in all your interactions with the project. + +## Pull Request Process + +When doing a PR to v2 remember that you also have to do the PR port to v3, or tests confirming the bug is not reproducible. + +1. Supported version is v3. If you are fixing a bug in v2, please port to v3 +2. Use the title as a brief description of the changes +3. Describe the changes you are proposing + 1. If adding an extra validation state the benefits of adding it and the problem is solving + 2. Document in the readme, by adding it to the list +4. Provide appropriate tests for the code you are submitting: aim to keep the existing coverage percentage. +5. Add your Twitter handle (if you have) so we can thank you there. + +## License +By contributing, you agree that your contributions will be licensed under its MIT License. + +## Code of Conduct + +### Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +### Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +### Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +### Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at . +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +#### Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +#### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +#### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +#### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +#### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/lib/egulias/email-validator/LICENSE b/lib/egulias/email-validator/LICENSE new file mode 100644 index 000000000..b1902a4e9 --- /dev/null +++ b/lib/egulias/email-validator/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2023 Eduardo Gulias Davis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/egulias/email-validator/composer.json b/lib/egulias/email-validator/composer.json new file mode 100644 index 000000000..bf1b3f4c9 --- /dev/null +++ b/lib/egulias/email-validator/composer.json @@ -0,0 +1,37 @@ +{ + "name": "egulias/email-validator", + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": ["email", "validation", "validator", "emailvalidation", "emailvalidator"], + "license": "MIT", + "authors": [ + {"name": "Eduardo Gulias Davis"} + ], + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "require": { + "php": ">=8.1", + "doctrine/lexer": "^2.0 || ^3.0", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Egulias\\EmailValidator\\Tests\\": "tests" + } + } +} diff --git a/lib/egulias/email-validator/src/EmailLexer.php b/lib/egulias/email-validator/src/EmailLexer.php new file mode 100644 index 000000000..a7fdc2d2c --- /dev/null +++ b/lib/egulias/email-validator/src/EmailLexer.php @@ -0,0 +1,329 @@ + */ +class EmailLexer extends AbstractLexer +{ + //ASCII values + public const S_EMPTY = -1; + public const C_NUL = 0; + public const S_HTAB = 9; + public const S_LF = 10; + public const S_CR = 13; + public const S_SP = 32; + public const EXCLAMATION = 33; + public const S_DQUOTE = 34; + public const NUMBER_SIGN = 35; + public const DOLLAR = 36; + public const PERCENTAGE = 37; + public const AMPERSAND = 38; + public const S_SQUOTE = 39; + public const S_OPENPARENTHESIS = 40; + public const S_CLOSEPARENTHESIS = 41; + public const ASTERISK = 42; + public const S_PLUS = 43; + public const S_COMMA = 44; + public const S_HYPHEN = 45; + public const S_DOT = 46; + public const S_SLASH = 47; + public const S_COLON = 58; + public const S_SEMICOLON = 59; + public const S_LOWERTHAN = 60; + public const S_EQUAL = 61; + public const S_GREATERTHAN = 62; + public const QUESTIONMARK = 63; + public const S_AT = 64; + public const S_OPENBRACKET = 91; + public const S_BACKSLASH = 92; + public const S_CLOSEBRACKET = 93; + public const CARET = 94; + public const S_UNDERSCORE = 95; + public const S_BACKTICK = 96; + public const S_OPENCURLYBRACES = 123; + public const S_PIPE = 124; + public const S_CLOSECURLYBRACES = 125; + public const S_TILDE = 126; + public const C_DEL = 127; + public const INVERT_QUESTIONMARK = 168; + public const INVERT_EXCLAMATION = 173; + public const GENERIC = 300; + public const S_IPV6TAG = 301; + public const INVALID = 302; + public const CRLF = 1310; + public const S_DOUBLECOLON = 5858; + public const ASCII_INVALID_FROM = 127; + public const ASCII_INVALID_TO = 199; + + /** + * US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3) + * + * @var array + */ + protected $charValue = [ + '{' => self::S_OPENCURLYBRACES, + '}' => self::S_CLOSECURLYBRACES, + '(' => self::S_OPENPARENTHESIS, + ')' => self::S_CLOSEPARENTHESIS, + '<' => self::S_LOWERTHAN, + '>' => self::S_GREATERTHAN, + '[' => self::S_OPENBRACKET, + ']' => self::S_CLOSEBRACKET, + ':' => self::S_COLON, + ';' => self::S_SEMICOLON, + '@' => self::S_AT, + '\\' => self::S_BACKSLASH, + '/' => self::S_SLASH, + ',' => self::S_COMMA, + '.' => self::S_DOT, + "'" => self::S_SQUOTE, + "`" => self::S_BACKTICK, + '"' => self::S_DQUOTE, + '-' => self::S_HYPHEN, + '::' => self::S_DOUBLECOLON, + ' ' => self::S_SP, + "\t" => self::S_HTAB, + "\r" => self::S_CR, + "\n" => self::S_LF, + "\r\n" => self::CRLF, + 'IPv6' => self::S_IPV6TAG, + '' => self::S_EMPTY, + '\0' => self::C_NUL, + '*' => self::ASTERISK, + '!' => self::EXCLAMATION, + '&' => self::AMPERSAND, + '^' => self::CARET, + '$' => self::DOLLAR, + '%' => self::PERCENTAGE, + '~' => self::S_TILDE, + '|' => self::S_PIPE, + '_' => self::S_UNDERSCORE, + '=' => self::S_EQUAL, + '+' => self::S_PLUS, + '¿' => self::INVERT_QUESTIONMARK, + '?' => self::QUESTIONMARK, + '#' => self::NUMBER_SIGN, + '¡' => self::INVERT_EXCLAMATION, + ]; + + public const INVALID_CHARS_REGEX = "/[^\p{S}\p{C}\p{Cc}]+/iu"; + + public const VALID_UTF8_REGEX = '/\p{Cc}+/u'; + + public const CATCHABLE_PATTERNS = [ + '[a-zA-Z]+[46]?', //ASCII and domain literal + '[^\x00-\x7F]', //UTF-8 + '[0-9]+', + '\r\n', + '::', + '\s+?', + '.', + ]; + + public const NON_CATCHABLE_PATTERNS = [ + '[\xA0-\xff]+', + ]; + + public const MODIFIERS = 'iu'; + + /** @var bool */ + protected $hasInvalidTokens = false; + + /** + * @var Token + */ + protected Token $previous; + + /** + * The last matched/seen token. + * + * @var Token + */ + public Token $current; + + /** + * @var Token + */ + private Token $nullToken; + + /** @var string */ + private $accumulator = ''; + + /** @var bool */ + private $hasToRecord = false; + + public function __construct() + { + /** @var Token $nullToken */ + $nullToken = new Token('', self::S_EMPTY, 0); + $this->nullToken = $nullToken; + + $this->current = $this->previous = $this->nullToken; + $this->lookahead = null; + } + + public function reset(): void + { + $this->hasInvalidTokens = false; + parent::reset(); + $this->current = $this->previous = $this->nullToken; + } + + /** + * @param int $type + * @throws \UnexpectedValueException + * @return boolean + * + */ + public function find($type): bool + { + $search = clone $this; + $search->skipUntil($type); + + if (!$search->lookahead) { + throw new \UnexpectedValueException($type . ' not found'); + } + return true; + } + + /** + * moveNext + * + * @return boolean + */ + public function moveNext(): bool + { + if ($this->hasToRecord && $this->previous === $this->nullToken) { + $this->accumulator .= $this->current->value; + } + + $this->previous = $this->current; + + if ($this->lookahead === null) { + $this->lookahead = $this->nullToken; + } + + $hasNext = parent::moveNext(); + $this->current = $this->token ?? $this->nullToken; + + if ($this->hasToRecord) { + $this->accumulator .= $this->current->value; + } + + return $hasNext; + } + + /** + * Retrieve token type. Also processes the token value if necessary. + * + * @param string $value + * @throws \InvalidArgumentException + * @return integer + */ + protected function getType(&$value): int + { + $encoded = $value; + + if (mb_detect_encoding($value, 'auto', true) !== 'UTF-8') { + $encoded = mb_convert_encoding($value, 'UTF-8', 'Windows-1252'); + } + + if ($this->isValid($encoded)) { + return $this->charValue[$encoded]; + } + + if ($this->isNullType($encoded)) { + return self::C_NUL; + } + + if ($this->isInvalidChar($encoded)) { + $this->hasInvalidTokens = true; + return self::INVALID; + } + + return self::GENERIC; + } + + protected function isValid(string $value): bool + { + return isset($this->charValue[$value]); + } + + protected function isNullType(string $value): bool + { + return $value === "\0"; + } + + protected function isInvalidChar(string $value): bool + { + return !preg_match(self::INVALID_CHARS_REGEX, $value); + } + + protected function isUTF8Invalid(string $value): bool + { + return preg_match(self::VALID_UTF8_REGEX, $value) !== false; + } + + public function hasInvalidTokens(): bool + { + return $this->hasInvalidTokens; + } + + /** + * getPrevious + * + * @return Token + */ + public function getPrevious(): Token + { + return $this->previous; + } + + /** + * Lexical catchable patterns. + * + * @return string[] + */ + protected function getCatchablePatterns(): array + { + return self::CATCHABLE_PATTERNS; + } + + /** + * Lexical non-catchable patterns. + * + * @return string[] + */ + protected function getNonCatchablePatterns(): array + { + return self::NON_CATCHABLE_PATTERNS; + } + + protected function getModifiers(): string + { + return self::MODIFIERS; + } + + public function getAccumulatedValues(): string + { + return $this->accumulator; + } + + public function startRecording(): void + { + $this->hasToRecord = true; + } + + public function stopRecording(): void + { + $this->hasToRecord = false; + } + + public function clearRecorded(): void + { + $this->accumulator = ''; + } +} diff --git a/lib/egulias/email-validator/src/EmailParser.php b/lib/egulias/email-validator/src/EmailParser.php new file mode 100644 index 000000000..fc449c76f --- /dev/null +++ b/lib/egulias/email-validator/src/EmailParser.php @@ -0,0 +1,90 @@ +addLongEmailWarning($this->localPart, $this->domainPart); + + return $result; + } + + protected function preLeftParsing(): Result + { + if (!$this->hasAtToken()) { + return new InvalidEmail(new NoLocalPart(), $this->lexer->current->value); + } + return new ValidEmail(); + } + + protected function parseLeftFromAt(): Result + { + return $this->processLocalPart(); + } + + protected function parseRightFromAt(): Result + { + return $this->processDomainPart(); + } + + private function processLocalPart(): Result + { + $localPartParser = new LocalPart($this->lexer); + $localPartResult = $localPartParser->parse(); + $this->localPart = $localPartParser->localPart(); + $this->warnings = [...$localPartParser->getWarnings(), ...$this->warnings]; + + return $localPartResult; + } + + private function processDomainPart(): Result + { + $domainPartParser = new DomainPart($this->lexer); + $domainPartResult = $domainPartParser->parse(); + $this->domainPart = $domainPartParser->domainPart(); + $this->warnings = [...$domainPartParser->getWarnings(), ...$this->warnings]; + + return $domainPartResult; + } + + public function getDomainPart(): string + { + return $this->domainPart; + } + + public function getLocalPart(): string + { + return $this->localPart; + } + + private function addLongEmailWarning(string $localPart, string $parsedDomainPart): void + { + if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) { + $this->warnings[EmailTooLong::CODE] = new EmailTooLong(); + } + } +} diff --git a/lib/egulias/email-validator/src/EmailValidator.php b/lib/egulias/email-validator/src/EmailValidator.php new file mode 100644 index 000000000..5a2e5c822 --- /dev/null +++ b/lib/egulias/email-validator/src/EmailValidator.php @@ -0,0 +1,67 @@ +lexer = new EmailLexer(); + } + + /** + * @param string $email + * @param EmailValidation $emailValidation + * @return bool + */ + public function isValid(string $email, EmailValidation $emailValidation) + { + $isValid = $emailValidation->isValid($email, $this->lexer); + $this->warnings = $emailValidation->getWarnings(); + $this->error = $emailValidation->getError(); + + return $isValid; + } + + /** + * @return boolean + */ + public function hasWarnings() + { + return !empty($this->warnings); + } + + /** + * @return array + */ + public function getWarnings() + { + return $this->warnings; + } + + /** + * @return InvalidEmail|null + */ + public function getError() + { + return $this->error; + } +} diff --git a/lib/egulias/email-validator/src/MessageIDParser.php b/lib/egulias/email-validator/src/MessageIDParser.php new file mode 100644 index 000000000..35bd0a7f1 --- /dev/null +++ b/lib/egulias/email-validator/src/MessageIDParser.php @@ -0,0 +1,91 @@ +addLongEmailWarning($this->idLeft, $this->idRight); + + return $result; + } + + protected function preLeftParsing(): Result + { + if (!$this->hasAtToken()) { + return new InvalidEmail(new NoLocalPart(), $this->lexer->current->value); + } + return new ValidEmail(); + } + + protected function parseLeftFromAt(): Result + { + return $this->processIDLeft(); + } + + protected function parseRightFromAt(): Result + { + return $this->processIDRight(); + } + + private function processIDLeft(): Result + { + $localPartParser = new IDLeftPart($this->lexer); + $localPartResult = $localPartParser->parse(); + $this->idLeft = $localPartParser->localPart(); + $this->warnings = [...$localPartParser->getWarnings(), ...$this->warnings]; + + return $localPartResult; + } + + private function processIDRight(): Result + { + $domainPartParser = new IDRightPart($this->lexer); + $domainPartResult = $domainPartParser->parse(); + $this->idRight = $domainPartParser->domainPart(); + $this->warnings = [...$domainPartParser->getWarnings(), ...$this->warnings]; + + return $domainPartResult; + } + + public function getLeftPart(): string + { + return $this->idLeft; + } + + public function getRightPart(): string + { + return $this->idRight; + } + + private function addLongEmailWarning(string $localPart, string $parsedDomainPart): void + { + if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAILID_MAX_LENGTH) { + $this->warnings[EmailTooLong::CODE] = new EmailTooLong(); + } + } +} diff --git a/lib/egulias/email-validator/src/Parser.php b/lib/egulias/email-validator/src/Parser.php new file mode 100644 index 000000000..d577e3eae --- /dev/null +++ b/lib/egulias/email-validator/src/Parser.php @@ -0,0 +1,78 @@ +lexer = $lexer; + } + + public function parse(string $str): Result + { + $this->lexer->setInput($str); + + if ($this->lexer->hasInvalidTokens()) { + return new InvalidEmail(new ExpectingATEXT("Invalid tokens found"), $this->lexer->current->value); + } + + $preParsingResult = $this->preLeftParsing(); + if ($preParsingResult->isInvalid()) { + return $preParsingResult; + } + + $localPartResult = $this->parseLeftFromAt(); + + if ($localPartResult->isInvalid()) { + return $localPartResult; + } + + $domainPartResult = $this->parseRightFromAt(); + + if ($domainPartResult->isInvalid()) { + return $domainPartResult; + } + + return new ValidEmail(); + } + + /** + * @return Warning\Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } + + protected function hasAtToken(): bool + { + $this->lexer->moveNext(); + $this->lexer->moveNext(); + + return !$this->lexer->current->isA(EmailLexer::S_AT); + } +} diff --git a/lib/egulias/email-validator/src/Parser/Comment.php b/lib/egulias/email-validator/src/Parser/Comment.php new file mode 100644 index 000000000..7b5b47e29 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/Comment.php @@ -0,0 +1,102 @@ +lexer = $lexer; + $this->commentStrategy = $commentStrategy; + } + + public function parse(): Result + { + if ($this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS)) { + $this->openedParenthesis++; + if ($this->noClosingParenthesis()) { + return new InvalidEmail(new UnclosedComment(), $this->lexer->current->value); + } + } + + if ($this->lexer->current->isA(EmailLexer::S_CLOSEPARENTHESIS)) { + return new InvalidEmail(new UnOpenedComment(), $this->lexer->current->value); + } + + $this->warnings[WarningComment::CODE] = new WarningComment(); + + $moreTokens = true; + while ($this->commentStrategy->exitCondition($this->lexer, $this->openedParenthesis) && $moreTokens) { + + if ($this->lexer->isNextToken(EmailLexer::S_OPENPARENTHESIS)) { + $this->openedParenthesis++; + } + $this->warnEscaping(); + if ($this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) { + $this->openedParenthesis--; + } + $moreTokens = $this->lexer->moveNext(); + } + + if ($this->openedParenthesis >= 1) { + return new InvalidEmail(new UnclosedComment(), $this->lexer->current->value); + } + if ($this->openedParenthesis < 0) { + return new InvalidEmail(new UnOpenedComment(), $this->lexer->current->value); + } + + $finalValidations = $this->commentStrategy->endOfLoopValidations($this->lexer); + + $this->warnings = [...$this->warnings, ...$this->commentStrategy->getWarnings()]; + + return $finalValidations; + } + + + /** + * @return void + */ + private function warnEscaping(): void + { + //Backslash found + if (!$this->lexer->current->isA(EmailLexer::S_BACKSLASH)) { + return; + } + + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) { + return; + } + + $this->warnings[QuotedPart::CODE] = + new QuotedPart($this->lexer->getPrevious()->type, $this->lexer->current->type); + } + + private function noClosingParenthesis(): bool + { + try { + $this->lexer->find(EmailLexer::S_CLOSEPARENTHESIS); + return false; + } catch (\RuntimeException $e) { + return true; + } + } +} diff --git a/lib/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php b/lib/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php new file mode 100644 index 000000000..8834db04c --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/CommentStrategy/CommentStrategy.php @@ -0,0 +1,22 @@ +isNextToken(EmailLexer::S_DOT)); + } + + public function endOfLoopValidations(EmailLexer $lexer): Result + { + //test for end of string + if (!$lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ExpectingATEXT('DOT not found near CLOSEPARENTHESIS'), $lexer->current->value); + } + //add warning + //Address is valid within the message but cannot be used unmodified for the envelope + return new ValidEmail(); + } + + public function getWarnings(): array + { + return []; + } +} diff --git a/lib/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php b/lib/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php new file mode 100644 index 000000000..5f30a90b8 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/CommentStrategy/LocalComment.php @@ -0,0 +1,38 @@ + + */ + private $warnings = []; + + public function exitCondition(EmailLexer $lexer, int $openedParenthesis): bool + { + return !$lexer->isNextToken(EmailLexer::S_AT); + } + + public function endOfLoopValidations(EmailLexer $lexer): Result + { + if (!$lexer->isNextToken(EmailLexer::S_AT)) { + return new InvalidEmail(new ExpectingATEXT('ATEX is not expected after closing comments'), $lexer->current->value); + } + $this->warnings[CFWSNearAt::CODE] = new CFWSNearAt(); + return new ValidEmail(); + } + + public function getWarnings(): array + { + return $this->warnings; + } +} diff --git a/lib/egulias/email-validator/src/Parser/DomainLiteral.php b/lib/egulias/email-validator/src/Parser/DomainLiteral.php new file mode 100644 index 000000000..5093e5083 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/DomainLiteral.php @@ -0,0 +1,210 @@ +addTagWarnings(); + + $IPv6TAG = false; + $addressLiteral = ''; + + do { + if ($this->lexer->current->isA(EmailLexer::C_NUL)) { + return new InvalidEmail(new ExpectingDTEXT(), $this->lexer->current->value); + } + + $this->addObsoleteWarnings(); + + if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENBRACKET, EmailLexer::S_OPENBRACKET))) { + return new InvalidEmail(new ExpectingDTEXT(), $this->lexer->current->value); + } + + if ($this->lexer->isNextTokenAny( + array(EmailLexer::S_HTAB, EmailLexer::S_SP, EmailLexer::CRLF) + )) { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + $this->parseFWS(); + } + + if ($this->lexer->isNextToken(EmailLexer::S_CR)) { + return new InvalidEmail(new CRNoLF(), $this->lexer->current->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_BACKSLASH)) { + return new InvalidEmail(new UnusualElements($this->lexer->current->value), $this->lexer->current->value); + } + if ($this->lexer->current->isA(EmailLexer::S_IPV6TAG)) { + $IPv6TAG = true; + } + + if ($this->lexer->current->isA(EmailLexer::S_CLOSEBRACKET)) { + break; + } + + $addressLiteral .= $this->lexer->current->value; + } while ($this->lexer->moveNext()); + + + //Encapsulate + $addressLiteral = str_replace('[', '', $addressLiteral); + $isAddressLiteralIPv4 = $this->checkIPV4Tag($addressLiteral); + + if (!$isAddressLiteralIPv4) { + return new ValidEmail(); + } + + $addressLiteral = $this->convertIPv4ToIPv6($addressLiteral); + + if (!$IPv6TAG) { + $this->warnings[WarningDomainLiteral::CODE] = new WarningDomainLiteral(); + return new ValidEmail(); + } + + $this->warnings[AddressLiteral::CODE] = new AddressLiteral(); + + $this->checkIPV6Tag($addressLiteral); + + return new ValidEmail(); + } + + /** + * @param string $addressLiteral + * @param int $maxGroups + */ + public function checkIPV6Tag($addressLiteral, $maxGroups = 8): void + { + $prev = $this->lexer->getPrevious(); + if ($prev->isA(EmailLexer::S_COLON)) { + $this->warnings[IPV6ColonEnd::CODE] = new IPV6ColonEnd(); + } + + $IPv6 = substr($addressLiteral, 5); + //Daniel Marschall's new IPv6 testing strategy + $matchesIP = explode(':', $IPv6); + $groupCount = count($matchesIP); + $colons = strpos($IPv6, '::'); + + if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) { + $this->warnings[IPV6BadChar::CODE] = new IPV6BadChar(); + } + + if ($colons === false) { + // We need exactly the right number of groups + if ($groupCount !== $maxGroups) { + $this->warnings[IPV6GroupCount::CODE] = new IPV6GroupCount(); + } + return; + } + + if ($colons !== strrpos($IPv6, '::')) { + $this->warnings[IPV6DoubleColon::CODE] = new IPV6DoubleColon(); + return; + } + + if ($colons === 0 || $colons === (strlen($IPv6) - 2)) { + // RFC 4291 allows :: at the start or end of an address + //with 7 other groups in addition + ++$maxGroups; + } + + if ($groupCount > $maxGroups) { + $this->warnings[IPV6MaxGroups::CODE] = new IPV6MaxGroups(); + } elseif ($groupCount === $maxGroups) { + $this->warnings[IPV6Deprecated::CODE] = new IPV6Deprecated(); + } + } + + public function convertIPv4ToIPv6(string $addressLiteralIPv4): string + { + $matchesIP = []; + $IPv4Match = preg_match(self::IPV4_REGEX, $addressLiteralIPv4, $matchesIP); + + // Extract IPv4 part from the end of the address-literal (if there is one) + if ($IPv4Match > 0) { + $index = (int) strrpos($addressLiteralIPv4, $matchesIP[0]); + //There's a match but it is at the start + if ($index > 0) { + // Convert IPv4 part to IPv6 format for further testing + return substr($addressLiteralIPv4, 0, $index) . '0:0'; + } + } + + return $addressLiteralIPv4; + } + + /** + * @param string $addressLiteral + * + * @return bool + */ + protected function checkIPV4Tag($addressLiteral): bool + { + $matchesIP = []; + $IPv4Match = preg_match(self::IPV4_REGEX, $addressLiteral, $matchesIP); + + // Extract IPv4 part from the end of the address-literal (if there is one) + + if ($IPv4Match > 0) { + $index = strrpos($addressLiteral, $matchesIP[0]); + //There's a match but it is at the start + if ($index === 0) { + $this->warnings[AddressLiteral::CODE] = new AddressLiteral(); + return false; + } + } + + return true; + } + + private function addObsoleteWarnings(): void + { + if (in_array($this->lexer->current->type, self::OBSOLETE_WARNINGS)) { + $this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT(); + } + } + + private function addTagWarnings(): void + { + if ($this->lexer->isNextToken(EmailLexer::S_COLON)) { + $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart(); + } + if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) { + $lexer = clone $this->lexer; + $lexer->moveNext(); + if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) { + $this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart(); + } + } + } +} diff --git a/lib/egulias/email-validator/src/Parser/DomainPart.php b/lib/egulias/email-validator/src/Parser/DomainPart.php new file mode 100644 index 000000000..3b6284b75 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/DomainPart.php @@ -0,0 +1,327 @@ +lexer->clearRecorded(); + $this->lexer->startRecording(); + + $this->lexer->moveNext(); + + $domainChecks = $this->performDomainStartChecks(); + if ($domainChecks->isInvalid()) { + return $domainChecks; + } + + if ($this->lexer->current->isA(EmailLexer::S_AT)) { + return new InvalidEmail(new ConsecutiveAt(), $this->lexer->current->value); + } + + $result = $this->doParseDomainPart(); + if ($result->isInvalid()) { + return $result; + } + + $end = $this->checkEndOfDomain(); + if ($end->isInvalid()) { + return $end; + } + + $this->lexer->stopRecording(); + $this->domainPart = $this->lexer->getAccumulatedValues(); + + $length = strlen($this->domainPart); + if ($length > self::DOMAIN_MAX_LENGTH) { + return new InvalidEmail(new DomainTooLong(), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + private function checkEndOfDomain(): Result + { + $prev = $this->lexer->getPrevious(); + if ($prev->isA(EmailLexer::S_DOT)) { + return new InvalidEmail(new DotAtEnd(), $this->lexer->current->value); + } + if ($prev->isA(EmailLexer::S_HYPHEN)) { + return new InvalidEmail(new DomainHyphened('Hypen found at the end of the domain'), $prev->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_SP)) { + return new InvalidEmail(new CRLFAtTheEnd(), $prev->value); + } + return new ValidEmail(); + } + + private function performDomainStartChecks(): Result + { + $invalidTokens = $this->checkInvalidTokensAfterAT(); + if ($invalidTokens->isInvalid()) { + return $invalidTokens; + } + + $missingDomain = $this->checkEmptyDomain(); + if ($missingDomain->isInvalid()) { + return $missingDomain; + } + + if ($this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS)) { + $this->warnings[DeprecatedComment::CODE] = new DeprecatedComment(); + } + return new ValidEmail(); + } + + private function checkEmptyDomain(): Result + { + $thereIsNoDomain = $this->lexer->current->isA(EmailLexer::S_EMPTY) || + ($this->lexer->current->isA(EmailLexer::S_SP) && + !$this->lexer->isNextToken(EmailLexer::GENERIC)); + + if ($thereIsNoDomain) { + return new InvalidEmail(new NoDomainPart(), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + private function checkInvalidTokensAfterAT(): Result + { + if ($this->lexer->current->isA(EmailLexer::S_DOT)) { + return new InvalidEmail(new DotAtStart(), $this->lexer->current->value); + } + if ($this->lexer->current->isA(EmailLexer::S_HYPHEN)) { + return new InvalidEmail(new DomainHyphened('After AT'), $this->lexer->current->value); + } + return new ValidEmail(); + } + + protected function parseComments(): Result + { + $commentParser = new Comment($this->lexer, new DomainComment()); + $result = $commentParser->parse(); + $this->warnings = [...$this->warnings, ...$commentParser->getWarnings()]; + + return $result; + } + + protected function doParseDomainPart(): Result + { + $tldMissing = true; + $hasComments = false; + $domain = ''; + do { + $prev = $this->lexer->getPrevious(); + + $notAllowedChars = $this->checkNotAllowedChars($this->lexer->current); + if ($notAllowedChars->isInvalid()) { + return $notAllowedChars; + } + + if ( + $this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS) || + $this->lexer->current->isA(EmailLexer::S_CLOSEPARENTHESIS) + ) { + $hasComments = true; + $commentsResult = $this->parseComments(); + + //Invalid comment parsing + if ($commentsResult->isInvalid()) { + return $commentsResult; + } + } + + $dotsResult = $this->checkConsecutiveDots(); + if ($dotsResult->isInvalid()) { + return $dotsResult; + } + + if ($this->lexer->current->isA(EmailLexer::S_OPENBRACKET)) { + $literalResult = $this->parseDomainLiteral(); + + $this->addTLDWarnings($tldMissing); + return $literalResult; + } + + $labelCheck = $this->checkLabelLength(); + if ($labelCheck->isInvalid()) { + return $labelCheck; + } + + $FwsResult = $this->parseFWS(); + if ($FwsResult->isInvalid()) { + return $FwsResult; + } + + $domain .= $this->lexer->current->value; + + if ($this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->isNextToken(EmailLexer::GENERIC)) { + $tldMissing = false; + } + + $exceptionsResult = $this->checkDomainPartExceptions($prev, $hasComments); + if ($exceptionsResult->isInvalid()) { + return $exceptionsResult; + } + $this->lexer->moveNext(); + } while (!$this->lexer->current->isA(EmailLexer::S_EMPTY)); + + $labelCheck = $this->checkLabelLength(true); + if ($labelCheck->isInvalid()) { + return $labelCheck; + } + $this->addTLDWarnings($tldMissing); + + $this->domainPart = $domain; + return new ValidEmail(); + } + + /** + * @param Token $token + * + * @return Result + */ + private function checkNotAllowedChars(Token $token): Result + { + $notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH => true]; + if (isset($notAllowed[$token->type])) { + return new InvalidEmail(new CharNotAllowed(), $token->value); + } + return new ValidEmail(); + } + + /** + * @return Result + */ + protected function parseDomainLiteral(): Result + { + try { + $this->lexer->find(EmailLexer::S_CLOSEBRACKET); + } catch (\RuntimeException $e) { + return new InvalidEmail(new ExpectingDomainLiteralClose(), $this->lexer->current->value); + } + + $domainLiteralParser = new DomainLiteralParser($this->lexer); + $result = $domainLiteralParser->parse(); + $this->warnings = [...$this->warnings, ...$domainLiteralParser->getWarnings()]; + return $result; + } + + /** + * @param Token $prev + * @param bool $hasComments + * + * @return Result + */ + protected function checkDomainPartExceptions(Token $prev, bool $hasComments): Result + { + if ($this->lexer->current->isA(EmailLexer::S_OPENBRACKET) && $prev->type !== EmailLexer::S_AT) { + return new InvalidEmail(new ExpectingATEXT('OPENBRACKET not after AT'), $this->lexer->current->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_HYPHEN) && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new DomainHyphened('Hypen found near DOT'), $this->lexer->current->value); + } + + if ( + $this->lexer->current->isA(EmailLexer::S_BACKSLASH) + && $this->lexer->isNextToken(EmailLexer::GENERIC) + ) { + return new InvalidEmail(new ExpectingATEXT('Escaping following "ATOM"'), $this->lexer->current->value); + } + + return $this->validateTokens($hasComments); + } + + protected function validateTokens(bool $hasComments): Result + { + $validDomainTokens = array( + EmailLexer::GENERIC => true, + EmailLexer::S_HYPHEN => true, + EmailLexer::S_DOT => true, + ); + + if ($hasComments) { + $validDomainTokens[EmailLexer::S_OPENPARENTHESIS] = true; + $validDomainTokens[EmailLexer::S_CLOSEPARENTHESIS] = true; + } + + if (!isset($validDomainTokens[$this->lexer->current->type])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token in domain: ' . $this->lexer->current->value), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + private function checkLabelLength(bool $isEndOfDomain = false): Result + { + if ($this->lexer->current->isA(EmailLexer::S_DOT) || $isEndOfDomain) { + if ($this->isLabelTooLong($this->label)) { + return new InvalidEmail(new LabelTooLong(), $this->lexer->current->value); + } + $this->label = ''; + } + $this->label .= $this->lexer->current->value; + return new ValidEmail(); + } + + + private function isLabelTooLong(string $label): bool + { + if (preg_match('/[^\x00-\x7F]/', $label)) { + idn_to_ascii($label, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $idnaInfo); + /** @psalm-var array{errors: int, ...} $idnaInfo */ + return (bool) ($idnaInfo['errors'] & IDNA_ERROR_LABEL_TOO_LONG); + } + return strlen($label) > self::LABEL_MAX_LENGTH; + } + + private function addTLDWarnings(bool $isTLDMissing): void + { + if ($isTLDMissing) { + $this->warnings[TLD::CODE] = new TLD(); + } + } + + public function domainPart(): string + { + return $this->domainPart; + } +} diff --git a/lib/egulias/email-validator/src/Parser/DoubleQuote.php b/lib/egulias/email-validator/src/Parser/DoubleQuote.php new file mode 100644 index 000000000..b5335d300 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/DoubleQuote.php @@ -0,0 +1,91 @@ +checkDQUOTE(); + if ($validQuotedString->isInvalid()) { + return $validQuotedString; + } + + $special = [ + EmailLexer::S_CR => true, + EmailLexer::S_HTAB => true, + EmailLexer::S_LF => true + ]; + + $invalid = [ + EmailLexer::C_NUL => true, + EmailLexer::S_HTAB => true, + EmailLexer::S_CR => true, + EmailLexer::S_LF => true + ]; + + $setSpecialsWarning = true; + + $this->lexer->moveNext(); + + while (!$this->lexer->current->isA(EmailLexer::S_DQUOTE) && !$this->lexer->current->isA(EmailLexer::S_EMPTY)) { + if (isset($special[$this->lexer->current->type]) && $setSpecialsWarning) { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + $setSpecialsWarning = false; + } + if ($this->lexer->current->isA(EmailLexer::S_BACKSLASH) && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) { + $this->lexer->moveNext(); + } + + $this->lexer->moveNext(); + + if (!$this->escaped() && isset($invalid[$this->lexer->current->type])) { + return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->current->value); + } + } + + $prev = $this->lexer->getPrevious(); + + if ($prev->isA(EmailLexer::S_BACKSLASH)) { + $validQuotedString = $this->checkDQUOTE(); + if ($validQuotedString->isInvalid()) { + return $validQuotedString; + } + } + + if (!$this->lexer->isNextToken(EmailLexer::S_AT) && !$prev->isA(EmailLexer::S_BACKSLASH)) { + return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + protected function checkDQUOTE(): Result + { + $previous = $this->lexer->getPrevious(); + + if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous->isA(EmailLexer::GENERIC)) { + $description = 'https://tools.ietf.org/html/rfc5322#section-3.2.4 - quoted string should be a unit'; + return new InvalidEmail(new ExpectingATEXT($description), $this->lexer->current->value); + } + + try { + $this->lexer->find(EmailLexer::S_DQUOTE); + } catch (\Exception $e) { + return new InvalidEmail(new UnclosedQuotedString(), $this->lexer->current->value); + } + $this->warnings[QuotedString::CODE] = new QuotedString($previous->value, $this->lexer->current->value); + + return new ValidEmail(); + } +} diff --git a/lib/egulias/email-validator/src/Parser/FoldingWhiteSpace.php b/lib/egulias/email-validator/src/Parser/FoldingWhiteSpace.php new file mode 100644 index 000000000..348a7af44 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/FoldingWhiteSpace.php @@ -0,0 +1,87 @@ +isFWS()) { + return new ValidEmail(); + } + + $previous = $this->lexer->getPrevious(); + + $resultCRLF = $this->checkCRLFInFWS(); + if ($resultCRLF->isInvalid()) { + return $resultCRLF; + } + + if ($this->lexer->current->isA(EmailLexer::S_CR)) { + return new InvalidEmail(new CRNoLF(), $this->lexer->current->value); + } + + if ($this->lexer->isNextToken(EmailLexer::GENERIC) && !$previous->isA(EmailLexer::S_AT)) { + return new InvalidEmail(new AtextAfterCFWS(), $this->lexer->current->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_LF) || $this->lexer->current->isA(EmailLexer::C_NUL)) { + return new InvalidEmail(new ExpectingCTEXT(), $this->lexer->current->value); + } + + if ($this->lexer->isNextToken(EmailLexer::S_AT) || $previous->isA(EmailLexer::S_AT)) { + $this->warnings[CFWSNearAt::CODE] = new CFWSNearAt(); + } else { + $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS(); + } + + return new ValidEmail(); + } + + protected function checkCRLFInFWS(): Result + { + if (!$this->lexer->current->isA(EmailLexer::CRLF)) { + return new ValidEmail(); + } + + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) { + return new InvalidEmail(new CRLFX2(), $this->lexer->current->value); + } + + //this has no coverage. Condition is repeated from above one + if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) { + return new InvalidEmail(new CRLFAtTheEnd(), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + protected function isFWS(): bool + { + if ($this->escaped()) { + return false; + } + + return in_array($this->lexer->current->type, self::FWS_TYPES); + } +} diff --git a/lib/egulias/email-validator/src/Parser/IDLeftPart.php b/lib/egulias/email-validator/src/Parser/IDLeftPart.php new file mode 100644 index 000000000..bedcf7b20 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/IDLeftPart.php @@ -0,0 +1,15 @@ +lexer->current->value); + } +} diff --git a/lib/egulias/email-validator/src/Parser/IDRightPart.php b/lib/egulias/email-validator/src/Parser/IDRightPart.php new file mode 100644 index 000000000..d2fc1d748 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/IDRightPart.php @@ -0,0 +1,29 @@ + true, + EmailLexer::S_SQUOTE => true, + EmailLexer::S_BACKTICK => true, + EmailLexer::S_SEMICOLON => true, + EmailLexer::S_GREATERTHAN => true, + EmailLexer::S_LOWERTHAN => true, + ]; + + if (isset($invalidDomainTokens[$this->lexer->current->type])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token in domain: ' . $this->lexer->current->value), $this->lexer->current->value); + } + return new ValidEmail(); + } +} diff --git a/lib/egulias/email-validator/src/Parser/LocalPart.php b/lib/egulias/email-validator/src/Parser/LocalPart.php new file mode 100644 index 000000000..10f956546 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/LocalPart.php @@ -0,0 +1,163 @@ + EmailLexer::S_COMMA, + EmailLexer::S_CLOSEBRACKET => EmailLexer::S_CLOSEBRACKET, + EmailLexer::S_OPENBRACKET => EmailLexer::S_OPENBRACKET, + EmailLexer::S_GREATERTHAN => EmailLexer::S_GREATERTHAN, + EmailLexer::S_LOWERTHAN => EmailLexer::S_LOWERTHAN, + EmailLexer::S_COLON => EmailLexer::S_COLON, + EmailLexer::S_SEMICOLON => EmailLexer::S_SEMICOLON, + EmailLexer::INVALID => EmailLexer::INVALID + ]; + + /** + * @var string + */ + private $localPart = ''; + + + public function parse(): Result + { + $this->lexer->clearRecorded(); + $this->lexer->startRecording(); + + while (!$this->lexer->current->isA(EmailLexer::S_AT) && !$this->lexer->current->isA(EmailLexer::S_EMPTY)) { + if ($this->hasDotAtStart()) { + return new InvalidEmail(new DotAtStart(), $this->lexer->current->value); + } + + if ($this->lexer->current->isA(EmailLexer::S_DQUOTE)) { + $dquoteParsingResult = $this->parseDoubleQuote(); + + //Invalid double quote parsing + if ($dquoteParsingResult->isInvalid()) { + return $dquoteParsingResult; + } + } + + if ( + $this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS) || + $this->lexer->current->isA(EmailLexer::S_CLOSEPARENTHESIS) + ) { + $commentsResult = $this->parseComments(); + + //Invalid comment parsing + if ($commentsResult->isInvalid()) { + return $commentsResult; + } + } + + if ($this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ConsecutiveDot(), $this->lexer->current->value); + } + + if ( + $this->lexer->current->isA(EmailLexer::S_DOT) && + $this->lexer->isNextToken(EmailLexer::S_AT) + ) { + return new InvalidEmail(new DotAtEnd(), $this->lexer->current->value); + } + + $resultEscaping = $this->validateEscaping(); + if ($resultEscaping->isInvalid()) { + return $resultEscaping; + } + + $resultToken = $this->validateTokens(false); + if ($resultToken->isInvalid()) { + return $resultToken; + } + + $resultFWS = $this->parseLocalFWS(); + if ($resultFWS->isInvalid()) { + return $resultFWS; + } + + $this->lexer->moveNext(); + } + + $this->lexer->stopRecording(); + $this->localPart = rtrim($this->lexer->getAccumulatedValues(), '@'); + if (strlen($this->localPart) > LocalTooLong::LOCAL_PART_LENGTH) { + $this->warnings[LocalTooLong::CODE] = new LocalTooLong(); + } + + return new ValidEmail(); + } + + protected function validateTokens(bool $hasComments): Result + { + if (isset(self::INVALID_TOKENS[$this->lexer->current->type])) { + return new InvalidEmail(new ExpectingATEXT('Invalid token found'), $this->lexer->current->value); + } + return new ValidEmail(); + } + + public function localPart(): string + { + return $this->localPart; + } + + private function parseLocalFWS(): Result + { + $foldingWS = new FoldingWhiteSpace($this->lexer); + $resultFWS = $foldingWS->parse(); + if ($resultFWS->isValid()) { + $this->warnings = [...$this->warnings, ...$foldingWS->getWarnings()]; + } + return $resultFWS; + } + + private function hasDotAtStart(): bool + { + return $this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->getPrevious()->isA(EmailLexer::S_EMPTY); + } + + private function parseDoubleQuote(): Result + { + $dquoteParser = new DoubleQuote($this->lexer); + $parseAgain = $dquoteParser->parse(); + $this->warnings = [...$this->warnings, ...$dquoteParser->getWarnings()]; + + return $parseAgain; + } + + protected function parseComments(): Result + { + $commentParser = new Comment($this->lexer, new LocalComment()); + $result = $commentParser->parse(); + $this->warnings = [...$this->warnings, ...$commentParser->getWarnings()]; + + return $result; + } + + private function validateEscaping(): Result + { + //Backslash found + if (!$this->lexer->current->isA(EmailLexer::S_BACKSLASH)) { + return new ValidEmail(); + } + + if ($this->lexer->isNextToken(EmailLexer::GENERIC)) { + return new InvalidEmail(new ExpectingATEXT('Found ATOM after escaping'), $this->lexer->current->value); + } + + return new ValidEmail(); + } +} diff --git a/lib/egulias/email-validator/src/Parser/PartParser.php b/lib/egulias/email-validator/src/Parser/PartParser.php new file mode 100644 index 000000000..53afb2575 --- /dev/null +++ b/lib/egulias/email-validator/src/Parser/PartParser.php @@ -0,0 +1,63 @@ +lexer = $lexer; + } + + abstract public function parse(): Result; + + /** + * @return Warning[] + */ + public function getWarnings() + { + return $this->warnings; + } + + protected function parseFWS(): Result + { + $foldingWS = new FoldingWhiteSpace($this->lexer); + $resultFWS = $foldingWS->parse(); + $this->warnings = [...$this->warnings, ...$foldingWS->getWarnings()]; + return $resultFWS; + } + + protected function checkConsecutiveDots(): Result + { + if ($this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->isNextToken(EmailLexer::S_DOT)) { + return new InvalidEmail(new ConsecutiveDot(), $this->lexer->current->value); + } + + return new ValidEmail(); + } + + protected function escaped(): bool + { + $previous = $this->lexer->getPrevious(); + + return $previous->isA(EmailLexer::S_BACKSLASH) + && !$this->lexer->current->isA(EmailLexer::GENERIC); + } +} diff --git a/lib/egulias/email-validator/src/Result/InvalidEmail.php b/lib/egulias/email-validator/src/Result/InvalidEmail.php new file mode 100644 index 000000000..82699acc6 --- /dev/null +++ b/lib/egulias/email-validator/src/Result/InvalidEmail.php @@ -0,0 +1,49 @@ +token = $token; + $this->reason = $reason; + } + + public function isValid(): bool + { + return false; + } + + public function isInvalid(): bool + { + return true; + } + + public function description(): string + { + return $this->reason->description() . " in char " . $this->token; + } + + public function code(): int + { + return $this->reason->code(); + } + + public function reason(): Reason + { + return $this->reason; + } +} diff --git a/lib/egulias/email-validator/src/Result/MultipleErrors.php b/lib/egulias/email-validator/src/Result/MultipleErrors.php new file mode 100644 index 000000000..5fa85afc9 --- /dev/null +++ b/lib/egulias/email-validator/src/Result/MultipleErrors.php @@ -0,0 +1,56 @@ +reasons[$reason->code()] = $reason; + } + + /** + * @return Reason[] + */ + public function getReasons() : array + { + return $this->reasons; + } + + public function reason() : Reason + { + return 0 !== count($this->reasons) + ? current($this->reasons) + : new EmptyReason(); + } + + public function description() : string + { + $description = ''; + foreach($this->reasons as $reason) { + $description .= $reason->description() . PHP_EOL; + } + + return $description; + } + + public function code() : int + { + return 0; + } +} diff --git a/lib/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php b/lib/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php new file mode 100644 index 000000000..96e22842f --- /dev/null +++ b/lib/egulias/email-validator/src/Result/Reason/AtextAfterCFWS.php @@ -0,0 +1,16 @@ +detailedDescription = $details; + } +} diff --git a/lib/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php b/lib/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php new file mode 100644 index 000000000..bcaefb68a --- /dev/null +++ b/lib/egulias/email-validator/src/Result/Reason/DomainAcceptsNoMail.php @@ -0,0 +1,16 @@ +exception = $exception; + + } + public function code() : int + { + return 999; + } + + public function description() : string + { + return $this->exception->getMessage(); + } +} diff --git a/lib/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php b/lib/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php new file mode 100644 index 000000000..07ea8d238 --- /dev/null +++ b/lib/egulias/email-validator/src/Result/Reason/ExpectingATEXT.php @@ -0,0 +1,16 @@ +detailedDescription; + } +} diff --git a/lib/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php b/lib/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php new file mode 100644 index 000000000..64f5f7c3e --- /dev/null +++ b/lib/egulias/email-validator/src/Result/Reason/ExpectingCTEXT.php @@ -0,0 +1,16 @@ +element = $element; + } + + public function code() : int + { + return 201; + } + + public function description() : string + { + return 'Unusual element found, wourld render invalid in majority of cases. Element found: ' . $this->element; + } +} diff --git a/lib/egulias/email-validator/src/Result/Result.php b/lib/egulias/email-validator/src/Result/Result.php new file mode 100644 index 000000000..0e50fc51c --- /dev/null +++ b/lib/egulias/email-validator/src/Result/Result.php @@ -0,0 +1,31 @@ +reason = new ReasonSpoofEmail(); + parent::__construct($this->reason, ''); + } +} diff --git a/lib/egulias/email-validator/src/Result/ValidEmail.php b/lib/egulias/email-validator/src/Result/ValidEmail.php new file mode 100644 index 000000000..fdc882fac --- /dev/null +++ b/lib/egulias/email-validator/src/Result/ValidEmail.php @@ -0,0 +1,27 @@ +dnsGetRecord = $dnsGetRecord; + } + + public function isValid(string $email, EmailLexer $emailLexer): bool + { + // use the input to check DNS if we cannot extract something similar to a domain + $host = $email; + + // Arguable pattern to extract the domain. Not aiming to validate the domain nor the email + if (false !== $lastAtPos = strrpos($email, '@')) { + $host = substr($email, $lastAtPos + 1); + } + + // Get the domain parts + $hostParts = explode('.', $host); + + $isLocalDomain = count($hostParts) <= 1; + $isReservedTopLevel = in_array($hostParts[(count($hostParts) - 1)], self::RESERVED_DNS_TOP_LEVEL_NAMES, true); + + // Exclude reserved top level DNS names + if ($isLocalDomain || $isReservedTopLevel) { + $this->error = new InvalidEmail(new LocalOrReservedDomain(), $host); + return false; + } + + return $this->checkDns($host); + } + + public function getError(): ?InvalidEmail + { + return $this->error; + } + + /** + * @return Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } + + /** + * @param string $host + * + * @return bool + */ + protected function checkDns($host) + { + $variant = INTL_IDNA_VARIANT_UTS46; + + $host = rtrim(idn_to_ascii($host, IDNA_DEFAULT, $variant), '.'); + + $hostParts = explode('.', $host); + $host = array_pop($hostParts); + + while (count($hostParts) > 0) { + $host = array_pop($hostParts) . '.' . $host; + + if ($this->validateDnsRecords($host)) { + return true; + } + } + + return false; + } + + + /** + * Validate the DNS records for given host. + * + * @param string $host A set of DNS records in the format returned by dns_get_record. + * + * @return bool True on success. + */ + private function validateDnsRecords($host): bool + { + $dnsRecordsResult = $this->dnsGetRecord->getRecords($host, DNS_A + DNS_MX); + + if ($dnsRecordsResult->withError()) { + $this->error = new InvalidEmail(new UnableToGetDNSRecord(), ''); + return false; + } + + $dnsRecords = $dnsRecordsResult->getRecords(); + + // Combined check for A+MX+AAAA can fail with SERVFAIL, even in the presence of valid A/MX records + $aaaaRecordsResult = $this->dnsGetRecord->getRecords($host, DNS_AAAA); + + if (! $aaaaRecordsResult->withError()) { + $dnsRecords = array_merge($dnsRecords, $aaaaRecordsResult->getRecords()); + } + + // No MX, A or AAAA DNS records + if ($dnsRecords === []) { + $this->error = new InvalidEmail(new ReasonNoDNSRecord(), ''); + return false; + } + + // For each DNS record + foreach ($dnsRecords as $dnsRecord) { + if (!$this->validateMXRecord($dnsRecord)) { + // No MX records (fallback to A or AAAA records) + if (empty($this->mxRecords)) { + $this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord(); + } + return false; + } + } + return true; + } + + /** + * Validate an MX record + * + * @param array $dnsRecord Given DNS record. + * + * @return bool True if valid. + */ + private function validateMxRecord($dnsRecord): bool + { + if (!isset($dnsRecord['type'])) { + $this->error = new InvalidEmail(new ReasonNoDNSRecord(), ''); + return false; + } + + if ($dnsRecord['type'] !== 'MX') { + return true; + } + + // "Null MX" record indicates the domain accepts no mail (https://tools.ietf.org/html/rfc7505) + if (empty($dnsRecord['target']) || $dnsRecord['target'] === '.') { + $this->error = new InvalidEmail(new DomainAcceptsNoMail(), ""); + return false; + } + + $this->mxRecords[] = $dnsRecord; + + return true; + } +} diff --git a/lib/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php b/lib/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php new file mode 100644 index 000000000..5d04c010c --- /dev/null +++ b/lib/egulias/email-validator/src/Validation/DNSGetRecordWrapper.php @@ -0,0 +1,30 @@ +> $records + * @param bool $error + */ + public function __construct(private readonly array $records, private readonly bool $error = false) + { + } + + /** + * @return list> + */ + public function getRecords(): array + { + return $this->records; + } + + public function withError(): bool + { + return $this->error; + } +} diff --git a/lib/egulias/email-validator/src/Validation/EmailValidation.php b/lib/egulias/email-validator/src/Validation/EmailValidation.php new file mode 100644 index 000000000..1bcc0a70b --- /dev/null +++ b/lib/egulias/email-validator/src/Validation/EmailValidation.php @@ -0,0 +1,34 @@ +setChecks(Spoofchecker::SINGLE_SCRIPT); + + if ($checker->isSuspicious($email)) { + $this->error = new SpoofEmail(); + } + + return $this->error === null; + } + + public function getError() : ?InvalidEmail + { + return $this->error; + } + + public function getWarnings() : array + { + return []; + } +} diff --git a/lib/egulias/email-validator/src/Validation/MessageIDValidation.php b/lib/egulias/email-validator/src/Validation/MessageIDValidation.php new file mode 100644 index 000000000..97d1ea7a7 --- /dev/null +++ b/lib/egulias/email-validator/src/Validation/MessageIDValidation.php @@ -0,0 +1,55 @@ +parse($email); + $this->warnings = $parser->getWarnings(); + if ($result->isInvalid()) { + /** @psalm-suppress PropertyTypeCoercion */ + $this->error = $result; + return false; + } + } catch (\Exception $invalid) { + $this->error = new InvalidEmail(new ExceptionFound($invalid), ''); + return false; + } + + return true; + } + + /** + * @return Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } + + public function getError(): ?InvalidEmail + { + return $this->error; + } +} diff --git a/lib/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php b/lib/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php new file mode 100644 index 000000000..c908053f3 --- /dev/null +++ b/lib/egulias/email-validator/src/Validation/MultipleValidationWithAnd.php @@ -0,0 +1,105 @@ +validations as $validation) { + $emailLexer->reset(); + $validationResult = $validation->isValid($email, $emailLexer); + $result = $result && $validationResult; + $this->warnings = [...$this->warnings, ...$validation->getWarnings()]; + if (!$validationResult) { + $this->processError($validation); + } + + if ($this->shouldStop($result)) { + break; + } + } + + return $result; + } + + private function initErrorStorage(): void + { + if (null === $this->error) { + $this->error = new MultipleErrors(); + } + } + + private function processError(EmailValidation $validation): void + { + if (null !== $validation->getError()) { + $this->initErrorStorage(); + /** @psalm-suppress PossiblyNullReference */ + $this->error->addReason($validation->getError()->reason()); + } + } + + private function shouldStop(bool $result): bool + { + return !$result && $this->mode === self::STOP_ON_ERROR; + } + + /** + * Returns the validation errors. + */ + public function getError(): ?InvalidEmail + { + return $this->error; + } + + /** + * @return Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } +} diff --git a/lib/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php b/lib/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php new file mode 100644 index 000000000..06885ed71 --- /dev/null +++ b/lib/egulias/email-validator/src/Validation/NoRFCWarningsValidation.php @@ -0,0 +1,41 @@ +getWarnings())) { + return true; + } + + $this->error = new InvalidEmail(new RFCWarnings(), ''); + + return false; + } + + /** + * {@inheritdoc} + */ + public function getError() : ?InvalidEmail + { + return $this->error ?: parent::getError(); + } +} diff --git a/lib/egulias/email-validator/src/Validation/RFCValidation.php b/lib/egulias/email-validator/src/Validation/RFCValidation.php new file mode 100644 index 000000000..f59cbfc80 --- /dev/null +++ b/lib/egulias/email-validator/src/Validation/RFCValidation.php @@ -0,0 +1,54 @@ +parse($email); + $this->warnings = $parser->getWarnings(); + if ($result->isInvalid()) { + /** @psalm-suppress PropertyTypeCoercion */ + $this->error = $result; + return false; + } + } catch (\Exception $invalid) { + $this->error = new InvalidEmail(new ExceptionFound($invalid), ''); + return false; + } + + return true; + } + + public function getError(): ?InvalidEmail + { + return $this->error; + } + + /** + * @return Warning[] + */ + public function getWarnings(): array + { + return $this->warnings; + } +} diff --git a/lib/egulias/email-validator/src/Warning/AddressLiteral.php b/lib/egulias/email-validator/src/Warning/AddressLiteral.php new file mode 100644 index 000000000..474ff0e75 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/AddressLiteral.php @@ -0,0 +1,14 @@ +message = 'Address literal in domain part'; + $this->rfcNumber = 5321; + } +} diff --git a/lib/egulias/email-validator/src/Warning/CFWSNearAt.php b/lib/egulias/email-validator/src/Warning/CFWSNearAt.php new file mode 100644 index 000000000..8bac12b1e --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/CFWSNearAt.php @@ -0,0 +1,13 @@ +message = "Deprecated folding white space near @"; + } +} diff --git a/lib/egulias/email-validator/src/Warning/CFWSWithFWS.php b/lib/egulias/email-validator/src/Warning/CFWSWithFWS.php new file mode 100644 index 000000000..ba57601c8 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/CFWSWithFWS.php @@ -0,0 +1,13 @@ +message = 'Folding whites space followed by folding white space'; + } +} diff --git a/lib/egulias/email-validator/src/Warning/Comment.php b/lib/egulias/email-validator/src/Warning/Comment.php new file mode 100644 index 000000000..6508295e3 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/Comment.php @@ -0,0 +1,13 @@ +message = "Comments found in this email"; + } +} diff --git a/lib/egulias/email-validator/src/Warning/DeprecatedComment.php b/lib/egulias/email-validator/src/Warning/DeprecatedComment.php new file mode 100644 index 000000000..a2578076e --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/DeprecatedComment.php @@ -0,0 +1,13 @@ +message = 'Deprecated comments'; + } +} diff --git a/lib/egulias/email-validator/src/Warning/DomainLiteral.php b/lib/egulias/email-validator/src/Warning/DomainLiteral.php new file mode 100644 index 000000000..034388c47 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/DomainLiteral.php @@ -0,0 +1,14 @@ +message = 'Domain Literal'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/egulias/email-validator/src/Warning/EmailTooLong.php b/lib/egulias/email-validator/src/Warning/EmailTooLong.php new file mode 100644 index 000000000..d25ad1234 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/EmailTooLong.php @@ -0,0 +1,15 @@ +message = 'Email is too long, exceeds ' . EmailParser::EMAIL_MAX_LENGTH; + } +} diff --git a/lib/egulias/email-validator/src/Warning/IPV6BadChar.php b/lib/egulias/email-validator/src/Warning/IPV6BadChar.php new file mode 100644 index 000000000..3ecd5bcca --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/IPV6BadChar.php @@ -0,0 +1,14 @@ +message = 'Bad char in IPV6 domain literal'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/egulias/email-validator/src/Warning/IPV6ColonEnd.php b/lib/egulias/email-validator/src/Warning/IPV6ColonEnd.php new file mode 100644 index 000000000..3f0c2f2df --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/IPV6ColonEnd.php @@ -0,0 +1,14 @@ +message = ':: found at the end of the domain literal'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/egulias/email-validator/src/Warning/IPV6ColonStart.php b/lib/egulias/email-validator/src/Warning/IPV6ColonStart.php new file mode 100644 index 000000000..742fb3bd1 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/IPV6ColonStart.php @@ -0,0 +1,14 @@ +message = ':: found at the start of the domain literal'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/egulias/email-validator/src/Warning/IPV6Deprecated.php b/lib/egulias/email-validator/src/Warning/IPV6Deprecated.php new file mode 100644 index 000000000..59c3037a5 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/IPV6Deprecated.php @@ -0,0 +1,14 @@ +message = 'Deprecated form of IPV6'; + $this->rfcNumber = 5321; + } +} diff --git a/lib/egulias/email-validator/src/Warning/IPV6DoubleColon.php b/lib/egulias/email-validator/src/Warning/IPV6DoubleColon.php new file mode 100644 index 000000000..d40660264 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/IPV6DoubleColon.php @@ -0,0 +1,14 @@ +message = 'Double colon found after IPV6 tag'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/egulias/email-validator/src/Warning/IPV6GroupCount.php b/lib/egulias/email-validator/src/Warning/IPV6GroupCount.php new file mode 100644 index 000000000..551bc3af1 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/IPV6GroupCount.php @@ -0,0 +1,14 @@ +message = 'Group count is not IPV6 valid'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/egulias/email-validator/src/Warning/IPV6MaxGroups.php b/lib/egulias/email-validator/src/Warning/IPV6MaxGroups.php new file mode 100644 index 000000000..7f8a410a8 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/IPV6MaxGroups.php @@ -0,0 +1,14 @@ +message = 'Reached the maximum number of IPV6 groups allowed'; + $this->rfcNumber = 5321; + } +} diff --git a/lib/egulias/email-validator/src/Warning/LocalTooLong.php b/lib/egulias/email-validator/src/Warning/LocalTooLong.php new file mode 100644 index 000000000..b46b874c0 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/LocalTooLong.php @@ -0,0 +1,15 @@ +message = 'Local part is too long, exceeds 64 chars (octets)'; + $this->rfcNumber = 5322; + } +} diff --git a/lib/egulias/email-validator/src/Warning/NoDNSMXRecord.php b/lib/egulias/email-validator/src/Warning/NoDNSMXRecord.php new file mode 100644 index 000000000..bddb96be7 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/NoDNSMXRecord.php @@ -0,0 +1,14 @@ +message = 'No MX DSN record was found for this email'; + $this->rfcNumber = 5321; + } +} diff --git a/lib/egulias/email-validator/src/Warning/ObsoleteDTEXT.php b/lib/egulias/email-validator/src/Warning/ObsoleteDTEXT.php new file mode 100644 index 000000000..412fd499e --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/ObsoleteDTEXT.php @@ -0,0 +1,14 @@ +rfcNumber = 5322; + $this->message = 'Obsolete DTEXT in domain literal'; + } +} diff --git a/lib/egulias/email-validator/src/Warning/QuotedPart.php b/lib/egulias/email-validator/src/Warning/QuotedPart.php new file mode 100644 index 000000000..db0850c9a --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/QuotedPart.php @@ -0,0 +1,27 @@ +name; + } + + if ($postToken instanceof UnitEnum) { + $postToken = $postToken->name; + } + + $this->message = "Deprecated Quoted String found between $prevToken and $postToken"; + } +} diff --git a/lib/egulias/email-validator/src/Warning/QuotedString.php b/lib/egulias/email-validator/src/Warning/QuotedString.php new file mode 100644 index 000000000..388da0bce --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/QuotedString.php @@ -0,0 +1,17 @@ +message = "Quoted String found between $prevToken and $postToken"; + } +} diff --git a/lib/egulias/email-validator/src/Warning/TLD.php b/lib/egulias/email-validator/src/Warning/TLD.php new file mode 100644 index 000000000..10cec2816 --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/TLD.php @@ -0,0 +1,13 @@ +message = "RFC5321, TLD"; + } +} diff --git a/lib/egulias/email-validator/src/Warning/Warning.php b/lib/egulias/email-validator/src/Warning/Warning.php new file mode 100644 index 000000000..7adb3b85c --- /dev/null +++ b/lib/egulias/email-validator/src/Warning/Warning.php @@ -0,0 +1,53 @@ +message; + } + + /** + * @return int + */ + public function code() + { + return self::CODE; + } + + /** + * @return int + */ + public function RFCNumber() + { + return $this->rfcNumber; + } + + /** + * @return string + */ + public function __toString(): string + { + return $this->message() . " rfc: " . $this->rfcNumber . "internal code: " . static::CODE; + } +} diff --git a/lib/guzzlehttp/guzzle/package-lock.json b/lib/guzzlehttp/guzzle/package-lock.json new file mode 100644 index 000000000..0e14dc181 --- /dev/null +++ b/lib/guzzlehttp/guzzle/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "guzzle", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/lib/laminas/laminas-loader/COPYRIGHT.md b/lib/laminas/laminas-loader/COPYRIGHT.md deleted file mode 100644 index 0a8cccc06..000000000 --- a/lib/laminas/laminas-loader/COPYRIGHT.md +++ /dev/null @@ -1 +0,0 @@ -Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) diff --git a/lib/laminas/laminas-loader/LICENSE.md b/lib/laminas/laminas-loader/LICENSE.md deleted file mode 100644 index 10b40f142..000000000 --- a/lib/laminas/laminas-loader/LICENSE.md +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -- Neither the name of Laminas Foundation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/laminas/laminas-loader/README.md b/lib/laminas/laminas-loader/README.md deleted file mode 100644 index a7529c920..000000000 --- a/lib/laminas/laminas-loader/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# laminas-loader - -> ## 🇷🇺 Русским гражданам -> -> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм. -> -> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую. -> -> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!" -> -> ## 🇺🇸 To Citizens of Russia -> -> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism. -> -> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences. -> -> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!" - - -> This package is considered feature-complete, and is now in **security-only** maintenance mode, following a [decision by the Technical Steering Committee](https://github.com/laminas/technical-steering-committee/blob/2b55453e172a1b8c9c4c212be7cf7e7a58b9352c/meetings/minutes/2020-08-03-TSC-Minutes.md#vote-on-components-to-mark-as-security-only). -> If you have a security issue, please [follow our security reporting guidelines](https://getlaminas.org/security/). -> If you wish to take on the role of maintainer, please [nominate yourself](https://github.com/laminas/technical-steering-committee/issues/new?assignees=&labels=Nomination&template=Maintainer_Nomination.md&title=%5BNOMINATION%5D%5BMAINTAINER%5D%3A+%7Bname+of+person+being+nominated%7D) - - -[![Build Status](https://github.com/laminas/laminas-loader/workflows/Continuous%20Integration/badge.svg)](https://github.com/laminas/laminas-loader/actions?query=workflow%3A"Continuous+Integration") - -laminas-loader provides different strategies for autoloading PHP classes. - -- File issues at https://github.com/laminas/laminas-loader/issues -- Documentation is at https://docs.laminas.dev/laminas-loader/ diff --git a/lib/laminas/laminas-loader/composer.json b/lib/laminas/laminas-loader/composer.json deleted file mode 100644 index 881509587..000000000 --- a/lib/laminas/laminas-loader/composer.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "laminas/laminas-loader", - "description": "Autoloading and plugin loading strategies", - "license": "BSD-3-Clause", - "keywords": [ - "laminas", - "loader" - ], - "homepage": "https://laminas.dev", - "support": { - "docs": "https://docs.laminas.dev/laminas-loader/", - "issues": "https://github.com/laminas/laminas-loader/issues", - "source": "https://github.com/laminas/laminas-loader", - "rss": "https://github.com/laminas/laminas-loader/releases.atom", - "chat": "https://laminas.dev/chat", - "forum": "https://discourse.laminas.dev" - }, - "config": { - "sort-packages": true, - "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true - } - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "~9.5.25" - }, - "autoload": { - "psr-4": { - "Laminas\\Loader\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "LaminasTest\\Loader\\": "test/" - } - }, - "scripts": { - "check": [ - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" - }, - "conflict": { - "zendframework/zend-loader": "*" - } -} diff --git a/lib/laminas/laminas-loader/composer.lock b/lib/laminas/laminas-loader/composer.lock deleted file mode 100644 index a7d09a27d..000000000 --- a/lib/laminas/laminas-loader/composer.lock +++ /dev/null @@ -1,2098 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "d00ced3d7abc2f3094a3205a51ef6376", - "packages": [], - "packages-dev": [ - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2022-02-04T12:51:07+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "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" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "laminas/laminas-coding-standard", - "version": "2.4.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-coding-standard.git", - "reference": "eb076dd86aa93dd424856b150c9b6f76c1fdfabc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/eb076dd86aa93dd424856b150c9b6f76c1fdfabc", - "reference": "eb076dd86aa93dd424856b150c9b6f76c1fdfabc", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", - "php": "^7.4 || ^8.0", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.6", - "webimpress/coding-standard": "^1.2" - }, - "conflict": { - "phpstan/phpdoc-parser": ">=1.6.0" - }, - "type": "phpcodesniffer-standard", - "autoload": { - "psr-4": { - "LaminasCodingStandard\\": "src/LaminasCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Laminas Coding Standard", - "homepage": "https://laminas.dev", - "keywords": [ - "Coding Standard", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-coding-standard/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-coding-standard/issues", - "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", - "source": "https://github.com/laminas/laminas-coding-standard" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-08-24T17:45:47+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "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" - }, - "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.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-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/v4.15.1" - }, - "time": "2022-09-04T07:30:47+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "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.3" - }, - "time": "2021-07-20T11:28:43+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": "phpstan/phpdoc-parser", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "981cc368a216c988e862a75e526b6076987d1b50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50", - "reference": "981cc368a216c988e862a75e526b6076987d1b50", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "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/1.5.1" - }, - "time": "2022-05-05T11:32:40+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.17", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "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" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.2-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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-08-30T12:24:04+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-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", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.25", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "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.13", - "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" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.5-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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.25" - }, - "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": "2022-09-25T03:44:45+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "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": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-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 types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "7.2.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phing/phing": "2.17.3", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.7.1", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2022-05-25T10:58:12+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "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" - } - ], - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "webimpress/coding-standard", - "version": "1.2.4", - "source": { - "type": "git", - "url": "https://github.com/webimpress/coding-standard.git", - "reference": "cd0c4b0b97440c337c1f7da17b524674ca2f9ca9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/cd0c4b0b97440c337c1f7da17b524674ca2f9ca9", - "reference": "cd0c4b0b97440c337c1f7da17b524674ca2f9ca9", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.13" - }, - "type": "phpcodesniffer-standard", - "extra": { - "dev-master": "1.2.x-dev", - "dev-develop": "1.3.x-dev" - }, - "autoload": { - "psr-4": { - "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "description": "Webimpress Coding Standard", - "keywords": [ - "Coding Standard", - "PSR-2", - "phpcs", - "psr-12", - "webimpress" - ], - "support": { - "issues": "https://github.com/webimpress/coding-standard/issues", - "source": "https://github.com/webimpress/coding-standard/tree/1.2.4" - }, - "funding": [ - { - "url": "https://github.com/michalbundyra", - "type": "github" - } - ], - "time": "2022-02-15T19:52:12+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "platform-dev": [], - "plugin-api-version": "2.6.0" -} diff --git a/lib/laminas/laminas-loader/src/AutoloaderFactory.php b/lib/laminas/laminas-loader/src/AutoloaderFactory.php deleted file mode 100644 index e1dabba1a..000000000 --- a/lib/laminas/laminas-loader/src/AutoloaderFactory.php +++ /dev/null @@ -1,212 +0,0 @@ - - * array( - * '' => $autoloaderOptions, - * ) - * - * - * The factory will then loop through and instantiate each autoloader with - * the specified options, and register each with the spl_autoloader. - * - * You may retrieve the concrete autoloader instances later using - * {@link getRegisteredAutoloaders()}. - * - * Note that the class names must be resolvable on the include_path or via - * the Laminas library, using PSR-0 rules (unless the class has already been - * loaded). - * - * @param array|Traversable $options (optional) options to use. Defaults to Laminas\Loader\StandardAutoloader - * @return void - * @throws Exception\InvalidArgumentException For invalid options. - * @throws Exception\InvalidArgumentException For unloadable autoloader classes. - * @throws Exception\DomainException For autoloader classes not implementing SplAutoloader. - */ - public static function factory($options = null) - { - if (null === $options) { - if (! isset(static::$loaders[static::STANDARD_AUTOLOADER])) { - $autoloader = static::getStandardAutoloader(); - $autoloader->register(); - static::$loaders[static::STANDARD_AUTOLOADER] = $autoloader; - } - - // Return so we don't hit the next check's exception (we're done here anyway) - return; - } - - if (! is_array($options) && ! $options instanceof Traversable) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException( - 'Options provided must be an array or Traversable' - ); - } - - foreach ($options as $class => $autoloaderOptions) { - if (! isset(static::$loaders[$class])) { - $autoloader = static::getStandardAutoloader(); - if (! class_exists($class) && ! $autoloader->autoload($class)) { - require_once 'Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException( - sprintf('Autoloader class "%s" not loaded', $class) - ); - } - - if (! is_subclass_of($class, SplAutoloader::class)) { - require_once 'Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException( - sprintf('Autoloader class %s must implement Laminas\\Loader\\SplAutoloader', $class) - ); - } - - if ($class === static::STANDARD_AUTOLOADER) { - $autoloader->setOptions($autoloaderOptions); - } else { - $autoloader = new $class($autoloaderOptions); - } - $autoloader->register(); - static::$loaders[$class] = $autoloader; - } else { - static::$loaders[$class]->setOptions($autoloaderOptions); - } - } - } - - /** - * Get a list of all autoloaders registered with the factory - * - * Returns an array of autoloader instances. - * - * @return array - */ - public static function getRegisteredAutoloaders() - { - return static::$loaders; - } - - /** - * Retrieves an autoloader by class name - * - * @param string $class - * @return SplAutoloader - * @throws Exception\InvalidArgumentException For non-registered class. - */ - public static function getRegisteredAutoloader($class) - { - if (! isset(static::$loaders[$class])) { - require_once 'Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException(sprintf('Autoloader class "%s" not loaded', $class)); - } - return static::$loaders[$class]; - } - - /** - * Unregisters all autoloaders that have been registered via the factory. - * This will NOT unregister autoloaders registered outside of the fctory. - * - * @return void - */ - public static function unregisterAutoloaders() - { - foreach (static::getRegisteredAutoloaders() as $class => $autoloader) { - spl_autoload_unregister([$autoloader, 'autoload']); - unset(static::$loaders[$class]); - } - } - - /** - * Unregister a single autoloader by class name - * - * @param string $autoloaderClass - * @return bool - */ - public static function unregisterAutoloader($autoloaderClass) - { - if (! isset(static::$loaders[$autoloaderClass])) { - return false; - } - - $autoloader = static::$loaders[$autoloaderClass]; - spl_autoload_unregister([$autoloader, 'autoload']); - unset(static::$loaders[$autoloaderClass]); - return true; - } - - /** - * Get an instance of the standard autoloader - * - * Used to attempt to resolve autoloader classes, using the - * StandardAutoloader. The instance is marked as a fallback autoloader, to - * allow resolving autoloaders not under the "Laminas" namespace. - * - * @return SplAutoloader - */ - protected static function getStandardAutoloader() - { - if (null !== static::$standardAutoloader) { - return static::$standardAutoloader; - } - - if (! class_exists(static::STANDARD_AUTOLOADER)) { - // Extract the filename from the classname - $stdAutoloader = substr(strrchr(static::STANDARD_AUTOLOADER, '\\'), 1); - require_once __DIR__ . "/$stdAutoloader.php"; - } - $loader = new StandardAutoloader(); - static::$standardAutoloader = $loader; - return static::$standardAutoloader; - } - - /** - * Checks if the object has this class as one of its parents - * - * @deprecated since laminas 2.3 requires PHP >= 5.3.23 - * - * @see https://bugs.php.net/bug.php?id=53727 - * @see https://github.com/zendframework/zf2/pull/1807 - * - * @param string $className - * @param string $type - * @return bool - */ - protected static function isSubclassOf($className, $type) - { - return is_subclass_of($className, $type); - } -} diff --git a/lib/laminas/laminas-loader/src/ClassMapAutoloader.php b/lib/laminas/laminas-loader/src/ClassMapAutoloader.php deleted file mode 100644 index b8edf3e61..000000000 --- a/lib/laminas/laminas-loader/src/ClassMapAutoloader.php +++ /dev/null @@ -1,234 +0,0 @@ -setOptions($options); - } - } - - /** - * Configure the autoloader - * - * Proxies to {@link registerAutoloadMaps()}. - * - * @param array|Traversable $options - * @return ClassMapAutoloader - */ - public function setOptions($options) - { - $this->registerAutoloadMaps($options); - return $this; - } - - /** - * Register an autoload map - * - * An autoload map may be either an associative array, or a file returning - * an associative array. - * - * An autoload map should be an associative array containing - * classname/file pairs. - * - * @param string|array $map - * @throws Exception\InvalidArgumentException - * @return ClassMapAutoloader - */ - public function registerAutoloadMap($map) - { - if (is_string($map)) { - $location = $map; - if ($this === ($map = $this->loadMapFromFile($location))) { - return $this; - } - } - - if (! is_array($map)) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException(sprintf( - 'Map file provided does not return a map. Map file: "%s"', - isset($location) && is_string($location) ? $location : 'unexpected type: ' . gettype($map) - )); - } - - $this->map = $map + $this->map; - - if (isset($location)) { - $this->mapsLoaded[] = $location; - } - - return $this; - } - - /** - * Register many autoload maps at once - * - * @param array $locations - * @throws Exception\InvalidArgumentException - * @return ClassMapAutoloader - */ - public function registerAutoloadMaps($locations) - { - if (! is_array($locations) && ! $locations instanceof Traversable) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException('Map list must be an array or implement Traversable'); - } - foreach ($locations as $location) { - $this->registerAutoloadMap($location); - } - return $this; - } - - /** - * Retrieve current autoload map - * - * @return array - */ - public function getAutoloadMap() - { - return $this->map; - } - - /** - * {@inheritDoc} - */ - public function autoload($class) - { - if (isset($this->map[$class])) { - require_once $this->map[$class]; - - return $class; - } - - return false; - } - - /** - * Register the autoloader with spl_autoload registry - * - * @return void - */ - public function register() - { - spl_autoload_register([$this, 'autoload'], true, true); - } - - /** - * Load a map from a file - * - * If the map has been previously loaded, returns the current instance; - * otherwise, returns whatever was returned by calling include() on the - * location. - * - * @param string $location - * @return ClassMapAutoloader|mixed - * @throws Exception\InvalidArgumentException For nonexistent locations. - */ - protected function loadMapFromFile($location) - { - if (! file_exists($location)) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException(sprintf( - 'Map file provided does not exist. Map file: "%s"', - is_string($location) ? $location : 'unexpected type: ' . gettype($location) - )); - } - - if (! $path = static::realPharPath($location)) { - $path = realpath($location); - } - - if (in_array($path, $this->mapsLoaded)) { - // Already loaded this map - return $this; - } - - return include $path; - } - - /** - * Resolve the real_path() to a file within a phar. - * - * @see https://bugs.php.net/bug.php?id=52769 - * - * @param string $path - * @return string - */ - public static function realPharPath($path) - { - if (! preg_match('|^phar:(/{2,3})|', $path, $match)) { - return; - } - - $prefixLength = 5 + strlen($match[1]); - $parts = explode('/', str_replace(['/', '\\'], '/', substr($path, $prefixLength))); - $parts = array_values(array_filter($parts, function ($p) { - return $p !== '' && $p !== '.'; - })); - - array_walk($parts, function ($value, $key) use (&$parts) { - if ($value === '..') { - unset($parts[$key], $parts[$key - 1]); - $parts = array_values($parts); - } - }); - - if (file_exists($realPath = str_pad('phar:', $prefixLength, '/') . implode('/', $parts))) { - return $realPath; - } - } -} diff --git a/lib/laminas/laminas-loader/src/Exception/BadMethodCallException.php b/lib/laminas/laminas-loader/src/Exception/BadMethodCallException.php deleted file mode 100644 index 98f08aa7d..000000000 --- a/lib/laminas/laminas-loader/src/Exception/BadMethodCallException.php +++ /dev/null @@ -1,10 +0,0 @@ - path */ - protected $explicitPaths = []; - - /** @var array An array of namespaceName => namespacePath */ - protected $namespacedPaths = []; - - /** @var string Will contain the absolute phar:// path to the executable when packaged as phar file */ - protected $pharBasePath = ""; - - /** @var array An array of supported phar extensions (filled on constructor) */ - protected $pharExtensions = []; - - /** @var array An array of module classes to their containing files */ - protected $moduleClassMap = []; - - /** - * Constructor - * - * Allow configuration of the autoloader via the constructor. - * - * @param null|array|Traversable $options - */ - public function __construct($options = null) - { - if (extension_loaded('phar')) { - $this->pharBasePath = Phar::running(true); - $this->pharExtensions = [ - 'phar', - 'phar.tar', - 'tar', - ]; - - // ext/zlib enabled -> phar can read gzip & zip compressed files - if (extension_loaded('zlib')) { - $this->pharExtensions[] = 'phar.gz'; - $this->pharExtensions[] = 'phar.tar.gz'; - $this->pharExtensions[] = 'tar.gz'; - - $this->pharExtensions[] = 'phar.zip'; - $this->pharExtensions[] = 'zip'; - } - - // ext/bzip2 enabled -> phar can read bz2 compressed files - if (extension_loaded('bzip2')) { - $this->pharExtensions[] = 'phar.bz2'; - $this->pharExtensions[] = 'phar.tar.bz2'; - $this->pharExtensions[] = 'tar.bz2'; - } - } - - if (null !== $options) { - $this->setOptions($options); - } - } - - /** - * Configure the autoloader - * - * In most cases, $options should be either an associative array or - * Traversable object. - * - * @param array|Traversable $options - * @return ModuleAutoloader - */ - public function setOptions($options) - { - $this->registerPaths($options); - return $this; - } - - /** - * Retrieves the class map for all loaded modules. - * - * @return array - */ - public function getModuleClassMap() - { - return $this->moduleClassMap; - } - - /** - * Sets the class map used to speed up the module autoloading. - * - * @param array $classmap - * @return ModuleAutoloader - */ - public function setModuleClassMap(array $classmap) - { - $this->moduleClassMap = $classmap; - - return $this; - } - - /** - * Autoload a class - * - * @param string $class - * @return mixed - * False [if unable to load $class] - * get_class($class) [if $class is successfully loaded] - */ - public function autoload($class) - { - // Limit scope of this autoloader - if (substr($class, -7) !== '\Module') { - return false; - } - - if (isset($this->moduleClassMap[$class])) { - require_once $this->moduleClassMap[$class]; - return $class; - } - - $moduleName = substr($class, 0, -7); - if (isset($this->explicitPaths[$moduleName])) { - $classLoaded = $this->loadModuleFromDir($this->explicitPaths[$moduleName], $class); - if ($classLoaded) { - return $classLoaded; - } - - $classLoaded = $this->loadModuleFromPhar($this->explicitPaths[$moduleName], $class); - if ($classLoaded) { - return $classLoaded; - } - } - - if (count($this->namespacedPaths) >= 1) { - foreach ($this->namespacedPaths as $namespace => $path) { - if (false === strpos($moduleName, $namespace)) { - continue; - } - - $moduleNameBuffer = str_replace($namespace . "\\", "", $moduleName); - $path .= DIRECTORY_SEPARATOR . $moduleNameBuffer . DIRECTORY_SEPARATOR; - - $classLoaded = $this->loadModuleFromDir($path, $class); - if ($classLoaded) { - return $classLoaded; - } - - $classLoaded = $this->loadModuleFromPhar($path, $class); - if ($classLoaded) { - return $classLoaded; - } - } - } - - $moduleClassPath = str_replace('\\', DIRECTORY_SEPARATOR, $moduleName); - - $pharSuffixPattern = null; - if ($this->pharExtensions) { - $pharSuffixPattern = '(' . implode('|', array_map('preg_quote', $this->pharExtensions)) . ')'; - } - - foreach ($this->paths as $path) { - $path .= $moduleClassPath; - - if ($path === '.' || substr($path, 0, 2) === './' || substr($path, 0, 2) === '.\\') { - if (! $basePath = $this->pharBasePath) { - $basePath = realpath('.'); - } - - if (false === $basePath) { - $basePath = getcwd(); - } - - $path = rtrim($basePath, '\/\\') . substr($path, 1); - } - - $classLoaded = $this->loadModuleFromDir($path, $class); - if ($classLoaded) { - return $classLoaded; - } - - // No directory with Module.php, searching for phars - if ($pharSuffixPattern) { - foreach (new GlobIterator($path . '.*') as $entry) { - if ($entry->isDir()) { - continue; - } - - if (! preg_match('#.+\.' . $pharSuffixPattern . '$#', $entry->getPathname())) { - continue; - } - - $classLoaded = $this->loadModuleFromPhar($entry->getPathname(), $class); - if ($classLoaded) { - return $classLoaded; - } - } - } - } - - return false; - } - - /** - * loadModuleFromDir - * - * @param string $dirPath - * @param string $class - * @return mixed - * False [if unable to load $class] - * get_class($class) [if $class is successfully loaded] - */ - protected function loadModuleFromDir($dirPath, $class) - { - $modulePath = $dirPath . '/Module.php'; - if (substr($modulePath, 0, 7) === 'phar://') { - $file = new PharFileInfo($modulePath); - } else { - $file = new SplFileInfo($modulePath); - } - - if ($file->isReadable() && $file->isFile()) { - // Found directory with Module.php in it - $absModulePath = $this->pharBasePath ? (string) $file : $file->getRealPath(); - require_once $absModulePath; - if (class_exists($class)) { - $this->moduleClassMap[$class] = $absModulePath; - return $class; - } - } - return false; - } - - /** - * loadModuleFromPhar - * - * @param string $pharPath - * @param string $class - * @return mixed - * False [if unable to load $class] - * get_class($class) [if $class is successfully loaded] - */ - protected function loadModuleFromPhar($pharPath, $class) - { - $pharPath = static::normalizePath($pharPath, false); - $file = new SplFileInfo($pharPath); - if (! $file->isReadable() || ! $file->isFile()) { - return false; - } - - $fileRealPath = $file->getRealPath(); - - // Phase 0: Check for executable phar with Module class in stub - if (strpos($fileRealPath, '.phar') !== false) { - // First see if the stub makes the Module class available - require_once $fileRealPath; - if (class_exists($class)) { - $this->moduleClassMap[$class] = $fileRealPath; - return $class; - } - } - - // Phase 1: Not executable phar, no stub, or stub did not provide Module class; try Module.php directly - $moduleClassFile = 'phar://' . $fileRealPath . '/Module.php'; - $moduleFile = new SplFileInfo($moduleClassFile); - if ($moduleFile->isReadable() && $moduleFile->isFile()) { - require_once $moduleClassFile; - if (class_exists($class)) { - $this->moduleClassMap[$class] = $moduleClassFile; - return $class; - } - } - - // Phase 2: Check for nested module directory within archive - // Checks for /path/to/MyModule.tar/MyModule/Module.php - // (shell-integrated zip/tar utilities wrap directories like this) - $pharBaseName = $this->pharFileToModuleName($fileRealPath); - $moduleClassFile = 'phar://' . $fileRealPath . '/' . $pharBaseName . '/Module.php'; - $moduleFile = new SplFileInfo($moduleClassFile); - if ($moduleFile->isReadable() && $moduleFile->isFile()) { - require_once $moduleClassFile; - if (class_exists($class)) { - $this->moduleClassMap[$class] = $moduleClassFile; - return $class; - } - } - - return false; - } - - /** - * Register the autoloader with spl_autoload registry - * - * @return void - */ - public function register() - { - spl_autoload_register([$this, 'autoload']); - } - - /** - * Unregister the autoloader with spl_autoload registry - * - * @return void - */ - public function unregister() - { - spl_autoload_unregister([$this, 'autoload']); - } - - /** - * registerPaths - * - * @param array|Traversable $paths - * @throws InvalidArgumentException - * @return ModuleAutoloader - */ - public function registerPaths($paths) - { - if (! is_array($paths) && ! $paths instanceof Traversable) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException( - 'Parameter to \\Laminas\\Loader\\ModuleAutoloader\'s ' - . 'registerPaths method must be an array or ' - . 'implement the Traversable interface' - ); - } - - foreach ($paths as $module => $path) { - if (is_string($module)) { - $this->registerPath($path, $module); - } else { - $this->registerPath($path); - } - } - - return $this; - } - - /** - * registerPath - * - * @param string $path - * @param bool|string $moduleName - * @throws InvalidArgumentException - * @return ModuleAutoloader - */ - public function registerPath($path, $moduleName = false) - { - if (! is_string($path)) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException(sprintf( - 'Invalid path provided; must be a string, received %s', - gettype($path) - )); - } - if ($moduleName) { - if (in_array(substr($moduleName, -2), ['\\*', '\\%'])) { - $this->namespacedPaths[substr($moduleName, 0, -2)] = static::normalizePath($path); - } else { - $this->explicitPaths[$moduleName] = static::normalizePath($path); - } - } else { - $this->paths[] = static::normalizePath($path); - } - return $this; - } - - /** - * getPaths - * - * This is primarily for unit testing, but could have other uses. - * - * @return array - */ - public function getPaths() - { - return $this->paths; - } - - /** - * Returns the base module name from the path to a phar - * - * @param string $pharPath - * @return string - */ - protected function pharFileToModuleName($pharPath) - { - do { - $pathinfo = pathinfo($pharPath); - $pharPath = $pathinfo['filename']; - } while (isset($pathinfo['extension'])); - return $pathinfo['filename']; - } - - /** - * Normalize a path for insertion in the stack - * - * @param string $path - * @param bool $trailingSlash Whether trailing slash should be included - * @return string - */ - public static function normalizePath($path, $trailingSlash = true) - { - $path = rtrim($path, '/'); - $path = rtrim($path, '\\'); - if ($trailingSlash) { - $path .= DIRECTORY_SEPARATOR; - } - return $path; - } -} diff --git a/lib/laminas/laminas-loader/src/PluginClassLoader.php b/lib/laminas/laminas-loader/src/PluginClassLoader.php deleted file mode 100644 index 0743cc7ae..000000000 --- a/lib/laminas/laminas-loader/src/PluginClassLoader.php +++ /dev/null @@ -1,223 +0,0 @@ - class name pairs - * - * @var array - */ - protected $plugins = []; - - /** - * Static map allow global seeding of plugin loader - * - * @var array - */ - protected static $staticMap = []; - - /** - * Constructor - * - * @param null|array|Traversable $map If provided, seeds the loader with a map - */ - public function __construct($map = null) - { - // Merge in static overrides - if (! empty(static::$staticMap)) { - $this->registerPlugins(static::$staticMap); - } - - // Merge in constructor arguments - if ($map !== null) { - $this->registerPlugins($map); - } - } - - /** - * Add a static map of plugins - * - * A null value will clear the static map. - * - * @param null|array|Traversable $map - * @throws Exception\InvalidArgumentException - * @return void - */ - public static function addStaticMap($map) - { - if (null === $map) { - static::$staticMap = []; - return; - } - - if (! is_array($map) && ! $map instanceof Traversable) { - throw new Exception\InvalidArgumentException('Expects an array or Traversable object'); - } - foreach ($map as $key => $value) { - static::$staticMap[$key] = $value; - } - } - - /** - * Register a class to a given short name - * - * @param string $shortName - * @param string $className - * @return PluginClassLoader - */ - public function registerPlugin($shortName, $className) - { - $this->plugins[strtolower($shortName)] = $className; - return $this; - } - - /** - * Register many plugins at once - * - * If $map is a string, assumes that the map is the class name of a - * Traversable object (likely a ShortNameLocator); it will then instantiate - * this class and use it to register plugins. - * - * If $map is an array or Traversable object, it will iterate it to - * register plugin names/classes. - * - * For all other arguments, or if the string $map is not a class or not a - * Traversable class, an exception will be raised. - * - * @param string|array|Traversable $map - * @return PluginClassLoader - * @throws Exception\InvalidArgumentException - */ - public function registerPlugins($map) - { - if (is_string($map)) { - if (! class_exists($map)) { - throw new Exception\InvalidArgumentException('Map class provided is invalid'); - } - $map = new $map(); - } - if (is_array($map)) { - $map = new ArrayIterator($map); - } - if (! $map instanceof Traversable) { - throw new Exception\InvalidArgumentException('Map provided is invalid; must be traversable'); - } - - // iterator_apply doesn't work as expected with IteratorAggregate - if ($map instanceof IteratorAggregate) { - $map = $map->getIterator(); - } - - foreach ($map as $name => $class) { - if (is_int($name) || is_numeric($name)) { - if (! is_object($class) && class_exists($class)) { - $class = new $class(); - } - - if ($class instanceof Traversable) { - $this->registerPlugins($class); - continue; - } - } - - $this->registerPlugin($name, $class); - } - - return $this; - } - - /** - * Unregister a short name lookup - * - * @param mixed $shortName - * @return PluginClassLoader - */ - public function unregisterPlugin($shortName) - { - $lookup = strtolower($shortName); - if (array_key_exists($lookup, $this->plugins)) { - unset($this->plugins[$lookup]); - } - return $this; - } - - /** - * Get a list of all registered plugins - * - * @return array|Traversable - */ - public function getRegisteredPlugins() - { - return $this->plugins; - } - - /** - * Whether or not a plugin by a specific name has been registered - * - * @param string $name - * @return bool - */ - public function isLoaded($name) - { - $lookup = strtolower($name); - return isset($this->plugins[$lookup]); - } - - /** - * Return full class name for a named helper - * - * @param string $name - * @return string|false - */ - public function getClassName($name) - { - return $this->load($name); - } - - /** - * Load a helper via the name provided - * - * @param string $name - * @return string|false - */ - public function load($name) - { - if (! $this->isLoaded($name)) { - return false; - } - return $this->plugins[strtolower($name)]; - } - - /** - * Defined by IteratorAggregate - * - * Returns an instance of ArrayIterator, containing a map of - * all plugins - * - * @return ArrayIterator - */ - #[ReturnTypeWillChange] - public function getIterator() - { - return new ArrayIterator($this->plugins); - } -} diff --git a/lib/laminas/laminas-loader/src/PluginClassLocator.php b/lib/laminas/laminas-loader/src/PluginClassLocator.php deleted file mode 100644 index 181b88ef8..000000000 --- a/lib/laminas/laminas-loader/src/PluginClassLocator.php +++ /dev/null @@ -1,36 +0,0 @@ - - * spl_autoload_register(array($this, 'autoload')); - * - * - * @return void - */ - public function register(); -} diff --git a/lib/laminas/laminas-loader/src/StandardAutoloader.php b/lib/laminas/laminas-loader/src/StandardAutoloader.php deleted file mode 100644 index 6d468187b..000000000 --- a/lib/laminas/laminas-loader/src/StandardAutoloader.php +++ /dev/null @@ -1,332 +0,0 @@ -setOptions($options); - } - } - - /** - * Configure autoloader - * - * Allows specifying both "namespace" and "prefix" pairs, using the - * following structure: - * - * array( - * 'namespaces' => array( - * 'Laminas' => '/path/to/Laminas/library', - * 'Doctrine' => '/path/to/Doctrine/library', - * ), - * 'prefixes' => array( - * 'Phly_' => '/path/to/Phly/library', - * ), - * 'fallback_autoloader' => true, - * ) - * - * - * @param array|Traversable $options - * @throws Exception\InvalidArgumentException - * @return StandardAutoloader - */ - public function setOptions($options) - { - if (! is_array($options) && ! $options instanceof Traversable) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException('Options must be either an array or Traversable'); - } - - foreach ($options as $type => $pairs) { - switch ($type) { - case self::AUTOREGISTER_LAMINAS: - if ($pairs) { - $this->registerNamespace('Laminas', dirname(__DIR__)); - } - break; - case self::LOAD_NS: - if (is_array($pairs) || $pairs instanceof Traversable) { - $this->registerNamespaces($pairs); - } - break; - case self::LOAD_PREFIX: - if (is_array($pairs) || $pairs instanceof Traversable) { - $this->registerPrefixes($pairs); - } - break; - case self::ACT_AS_FALLBACK: - $this->setFallbackAutoloader($pairs); - break; - default: - // ignore - } - } - return $this; - } - - /** - * Set flag indicating fallback autoloader status - * - * @param bool $flag - * @return StandardAutoloader - */ - public function setFallbackAutoloader($flag) - { - $this->fallbackAutoloaderFlag = (bool) $flag; - return $this; - } - - /** - * Is this autoloader acting as a fallback autoloader? - * - * @return bool - */ - public function isFallbackAutoloader() - { - return $this->fallbackAutoloaderFlag; - } - - /** - * Register a namespace/directory pair - * - * @param string $namespace - * @param string $directory - * @return StandardAutoloader - */ - public function registerNamespace($namespace, $directory) - { - $namespace = rtrim($namespace, self::NS_SEPARATOR) . self::NS_SEPARATOR; - $this->namespaces[$namespace] = $this->normalizeDirectory($directory); - return $this; - } - - /** - * Register many namespace/directory pairs at once - * - * @param array $namespaces - * @throws Exception\InvalidArgumentException - * @return StandardAutoloader - */ - public function registerNamespaces($namespaces) - { - if (! is_array($namespaces) && ! $namespaces instanceof Traversable) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException('Namespace pairs must be either an array or Traversable'); - } - - foreach ($namespaces as $namespace => $directory) { - $this->registerNamespace($namespace, $directory); - } - return $this; - } - - /** - * Register a prefix/directory pair - * - * @param string $prefix - * @param string $directory - * @return StandardAutoloader - */ - public function registerPrefix($prefix, $directory) - { - $prefix = rtrim($prefix, self::PREFIX_SEPARATOR) . self::PREFIX_SEPARATOR; - $this->prefixes[$prefix] = $this->normalizeDirectory($directory); - return $this; - } - - /** - * Register many namespace/directory pairs at once - * - * @param array $prefixes - * @throws Exception\InvalidArgumentException - * @return StandardAutoloader - */ - public function registerPrefixes($prefixes) - { - if (! is_array($prefixes) && ! $prefixes instanceof Traversable) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException('Prefix pairs must be either an array or Traversable'); - } - - foreach ($prefixes as $prefix => $directory) { - $this->registerPrefix($prefix, $directory); - } - return $this; - } - - /** - * Defined by Autoloadable; autoload a class - * - * @param string $class - * @return false|string - */ - public function autoload($class) - { - $isFallback = $this->isFallbackAutoloader(); - if (false !== strpos($class, self::NS_SEPARATOR)) { - if ($this->loadClass($class, self::LOAD_NS)) { - return $class; - } elseif ($isFallback) { - return $this->loadClass($class, self::ACT_AS_FALLBACK); - } - return false; - } - if (false !== strpos($class, self::PREFIX_SEPARATOR)) { - if ($this->loadClass($class, self::LOAD_PREFIX)) { - return $class; - } elseif ($isFallback) { - return $this->loadClass($class, self::ACT_AS_FALLBACK); - } - return false; - } - if ($isFallback) { - return $this->loadClass($class, self::ACT_AS_FALLBACK); - } - return false; - } - - /** - * Register the autoloader with spl_autoload - * - * @return void - */ - public function register() - { - spl_autoload_register([$this, 'autoload']); - } - - /** - * Transform the class name to a filename - * - * @param string $class - * @param string $directory - * @return string - */ - protected function transformClassNameToFilename($class, $directory) - { - // $class may contain a namespace portion, in which case we need - // to preserve any underscores in that portion. - $matches = []; - preg_match('/(?P.+\\\)?(?P[^\\\]+$)/', $class, $matches); - - $class = $matches['class'] ?? ''; - $namespace = $matches['namespace'] ?? ''; - - return $directory - . str_replace(self::NS_SEPARATOR, '/', $namespace) - . str_replace(self::PREFIX_SEPARATOR, '/', $class) - . '.php'; - } - - /** - * Load a class, based on its type (namespaced or prefixed) - * - * @param string $class - * @param string $type - * @return bool|string - * @throws Exception\InvalidArgumentException - */ - protected function loadClass($class, $type) - { - if (! in_array($type, [self::LOAD_NS, self::LOAD_PREFIX, self::ACT_AS_FALLBACK])) { - require_once __DIR__ . '/Exception/InvalidArgumentException.php'; - throw new Exception\InvalidArgumentException(); - } - - // Fallback autoloading - if ($type === self::ACT_AS_FALLBACK) { - // create filename - $filename = $this->transformClassNameToFilename($class, ''); - $resolvedName = stream_resolve_include_path($filename); - if ($resolvedName !== false) { - return include $resolvedName; - } - return false; - } - - // Namespace and/or prefix autoloading - foreach ($this->$type as $leader => $path) { - if (0 === strpos($class, $leader)) { - // Trim off leader (namespace or prefix) - $trimmedClass = substr($class, strlen($leader)); - - // create filename - $filename = $this->transformClassNameToFilename($trimmedClass, $path); - if (file_exists($filename)) { - return include $filename; - } - } - } - return false; - } - - /** - * Normalize the directory to include a trailing directory separator - * - * @param string $directory - * @return string - */ - protected function normalizeDirectory($directory) - { - $last = $directory[strlen($directory) - 1]; - if (in_array($last, ['/', '\\'])) { - $directory[strlen($directory) - 1] = DIRECTORY_SEPARATOR; - return $directory; - } - $directory .= DIRECTORY_SEPARATOR; - return $directory; - } -} diff --git a/lib/laminas/laminas-mail/COPYRIGHT.md b/lib/laminas/laminas-mail/COPYRIGHT.md deleted file mode 100644 index 0a8cccc06..000000000 --- a/lib/laminas/laminas-mail/COPYRIGHT.md +++ /dev/null @@ -1 +0,0 @@ -Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) diff --git a/lib/laminas/laminas-mail/LICENSE.md b/lib/laminas/laminas-mail/LICENSE.md deleted file mode 100644 index 10b40f142..000000000 --- a/lib/laminas/laminas-mail/LICENSE.md +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -- Neither the name of Laminas Foundation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/laminas/laminas-mail/README.md b/lib/laminas/laminas-mail/README.md deleted file mode 100644 index 8c6ac60c4..000000000 --- a/lib/laminas/laminas-mail/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# laminas-mail - -[![Build Status](https://github.com/laminas/laminas-mail/workflows/Continuous%20Integration/badge.svg)](https://github.com/laminas/laminas-mail/actions?query=workflow%3A"Continuous+Integration") - -> ## 🇷🇺 Русским гражданам -> -> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм. -> -> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую. -> -> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!" -> -> ## 🇺🇸 To Citizens of Russia -> -> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism. -> -> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences. -> -> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!" - -`Laminas\Mail` provides generalized functionality to compose and send both text and -MIME-compliant multipart email messages. Mail can be sent with `Laminas\Mail` via -the `Mail\Transport\Sendmail`, `Mail\Transport\Smtp` or the `Mail\Transport\File` -transport. Of course, you can also implement your own transport by implementing -the `Mail\Transport\TransportInterface`. - -- File issues at https://github.com/laminas/laminas-mail/issues -- Documentation is at https://docs.laminas.dev/laminas-mail/ diff --git a/lib/laminas/laminas-mail/composer.json b/lib/laminas/laminas-mail/composer.json deleted file mode 100644 index f06b205e6..000000000 --- a/lib/laminas/laminas-mail/composer.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "laminas/laminas-mail", - "description": "Provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", - "keywords": [ - "laminas", - "mail" - ], - "homepage": "https://laminas.dev", - "license": "BSD-3-Clause", - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "ext-iconv": "*", - "laminas/laminas-loader": "^2.8.0", - "laminas/laminas-mime": "^2.10.0", - "laminas/laminas-stdlib": "^3.11.0", - "laminas/laminas-validator": "^2.23.0", - "symfony/polyfill-mbstring": "^1.16.0", - "webmozart/assert": "^1.11.0", - "symfony/polyfill-intl-idn": "^1.26.0" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-crypt": "^3.9.0", - "laminas/laminas-db": "^2.16", - "laminas/laminas-servicemanager": "^3.20", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.4", - "symfony/process": "^6.0.11", - "vimeo/psalm": "^5.1" - }, - "suggest": { - "laminas/laminas-crypt": "^3.8 Crammd5 support in SMTP Auth", - "laminas/laminas-servicemanager": "^3.16 when using SMTP to deliver messages" - }, - "config": { - "sort-packages": true, - "allow-plugins": { - "composer/package-versions-deprecated": true, - "dealerdirect/phpcodesniffer-composer-installer": true - }, - "platform": { - "php": "8.0.99" - } - }, - "extra": { - "laminas": { - "component": "Laminas\\Mail", - "config-provider": "Laminas\\Mail\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Mail\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "LaminasTest\\Mail\\": "test/" - } - }, - "scripts": { - "check": [ - "@cs-check", - "@static-analysis", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "static-analysis": "psalm --shepherd --stats", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" - }, - "support": { - "issues": "https://github.com/laminas/laminas-mail/issues", - "forum": "https://discourse.laminas.dev", - "chat": "https://laminas.dev/chat", - "source": "https://github.com/laminas/laminas-mail", - "docs": "https://docs.laminas.dev/laminas-mail/", - "rss": "https://github.com/laminas/laminas-mail/releases.atom" - } -} diff --git a/lib/laminas/laminas-mail/composer.lock b/lib/laminas/laminas-mail/composer.lock deleted file mode 100644 index 7c4ecf66b..000000000 --- a/lib/laminas/laminas-mail/composer.lock +++ /dev/null @@ -1,4985 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "cd0e70dcc0432b9ec92dce8a606d0246", - "packages": [ - { - "name": "laminas/laminas-loader", - "version": "2.9.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-loader.git", - "reference": "51ed9c3fa42d1098a9997571730c0cbf42d078d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/51ed9c3fa42d1098a9997571730c0cbf42d078d3", - "reference": "51ed9c3fa42d1098a9997571730c0cbf42d078d3", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-loader": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "~9.5.25" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Loader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Autoloading and plugin loading strategies", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "loader" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-loader/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-loader/issues", - "rss": "https://github.com/laminas/laminas-loader/releases.atom", - "source": "https://github.com/laminas/laminas-loader" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-16T12:50:49+00:00" - }, - { - "name": "laminas/laminas-mime", - "version": "2.11.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-mime.git", - "reference": "60ec04b755821c79c1987ce291b44e69f2c0831f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-mime/zipball/60ec04b755821c79c1987ce291b44e69f2c0831f", - "reference": "60ec04b755821c79c1987ce291b44e69f2c0831f", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^2.7 || ^3.0", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-mime": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-mail": "^2.19.0", - "phpunit/phpunit": "~9.5.25" - }, - "suggest": { - "laminas/laminas-mail": "Laminas\\Mail component" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Mime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Create and parse MIME messages and parts", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "mime" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-mime/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-mime/issues", - "rss": "https://github.com/laminas/laminas-mime/releases.atom", - "source": "https://github.com/laminas/laminas-mime" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-18T08:38:15+00:00" - }, - { - "name": "laminas/laminas-servicemanager", - "version": "3.20.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "bc2c2cbe2dd90db8b9d16b0618f542692b76ab59" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/bc2c2cbe2dd90db8b9d16b0618f542692b76ab59", - "reference": "bc2c2cbe2dd90db8b9d16b0618f542692b76ab59", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.2.1", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "psr/container": "^1.0" - }, - "conflict": { - "ext-psr": "*", - "laminas/laminas-code": "<3.3.1", - "zendframework/zend-code": "<3.3.1", - "zendframework/zend-servicemanager": "*" - }, - "provide": { - "psr/container-implementation": "^1.0" - }, - "replace": { - "container-interop/container-interop": "^1.2.0" - }, - "require-dev": { - "composer/package-versions-deprecated": "^1.11.99.5", - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-container-config-test": "^0.8", - "laminas/laminas-dependency-plugin": "^2.2", - "mikey179/vfsstream": "^1.6.11@alpha", - "ocramius/proxy-manager": "^2.14.1", - "phpbench/phpbench": "^1.2.7", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.0", - "vimeo/psalm": "^5.0.0" - }, - "suggest": { - "ocramius/proxy-manager": "ProxyManager ^2.1.1 to handle lazy initialization of services" - }, - "bin": [ - "bin/generate-deps-for-config-factory", - "bin/generate-factory-for-class" - ], - "type": "library", - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Laminas\\ServiceManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Factory-Driven Dependency Injection Container", - "homepage": "https://laminas.dev", - "keywords": [ - "PSR-11", - "dependency-injection", - "di", - "dic", - "laminas", - "service-manager", - "servicemanager" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-servicemanager/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-servicemanager/issues", - "rss": "https://github.com/laminas/laminas-servicemanager/releases.atom", - "source": "https://github.com/laminas/laminas-servicemanager" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-12-01T17:03:38+00:00" - }, - { - "name": "laminas/laminas-stdlib", - "version": "3.16.1", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "f4f773641807c7ccee59b758bfe4ac4ba33ecb17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/f4f773641807c7ccee59b758bfe4ac4ba33ecb17", - "reference": "f4f773641807c7ccee59b758bfe4ac4ba33ecb17", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-stdlib": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "phpbench/phpbench": "^1.2.7", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.0", - "vimeo/psalm": "^5.0.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Stdlib\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "SPL extensions, array utilities, error handlers, and more", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "stdlib" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-stdlib/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-stdlib/issues", - "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", - "source": "https://github.com/laminas/laminas-stdlib" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-12-03T18:48:01+00:00" - }, - { - "name": "laminas/laminas-validator", - "version": "2.29.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-validator.git", - "reference": "e40ee8d86cc1907083e273bfd6ed8b6dde2d9850" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/e40ee8d86cc1907083e273bfd6ed8b6dde2d9850", - "reference": "e40ee8d86cc1907083e273bfd6ed8b6dde2d9850", - "shasum": "" - }, - "require": { - "laminas/laminas-servicemanager": "^3.12.0", - "laminas/laminas-stdlib": "^3.13", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "psr/http-message": "^1.0.1" - }, - "conflict": { - "zendframework/zend-validator": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "laminas/laminas-db": "^2.16", - "laminas/laminas-filter": "^2.28.1", - "laminas/laminas-http": "^2.18", - "laminas/laminas-i18n": "^2.19", - "laminas/laminas-session": "^2.15", - "laminas/laminas-uri": "^2.10.0", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.3", - "psr/http-client": "^1.0.1", - "psr/http-factory": "^1.0.1", - "vimeo/psalm": "^5.0" - }, - "suggest": { - "laminas/laminas-db": "Laminas\\Db component, required by the (No)RecordExists validator", - "laminas/laminas-filter": "Laminas\\Filter component, required by the Digits validator", - "laminas/laminas-i18n": "Laminas\\I18n component to allow translation of validation error messages", - "laminas/laminas-i18n-resources": "Translations of validator messages", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", - "laminas/laminas-session": "Laminas\\Session component, ^2.8; required by the Csrf validator", - "laminas/laminas-uri": "Laminas\\Uri component, required by the Uri and Sitemap\\Loc validators", - "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Validator", - "config-provider": "Laminas\\Validator\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Validator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "validator" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-validator/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-validator/issues", - "rss": "https://github.com/laminas/laminas-validator/releases.atom", - "source": "https://github.com/laminas/laminas-validator" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-12-13T22:53:38+00:00" - }, - { - "name": "psr/container", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "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/1.1.2" - }, - "time": "2021-11-05T16:50:12+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.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": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "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": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "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" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+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" - } - ], - "packages-dev": [ - { - "name": "amphp/amp", - "version": "v2.6.2", - "source": { - "type": "git", - "url": "https://github.com/amphp/amp.git", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^7 | ^8 | ^9", - "psalm/phar": "^3.11@dev", - "react/promise": "^2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php", - "lib/Internal/functions.php" - ], - "psr-4": { - "Amp\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "https://amphp.org/amp", - "keywords": [ - "async", - "asynchronous", - "awaitable", - "concurrency", - "event", - "event-loop", - "future", - "non-blocking", - "promise" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.2" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2022-02-20T17:52:18+00:00" - }, - { - "name": "amphp/byte-stream", - "version": "v1.8.1", - "source": { - "type": "git", - "url": "https://github.com/amphp/byte-stream.git", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", - "shasum": "" - }, - "require": { - "amphp/amp": "^2", - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.4", - "friendsofphp/php-cs-fixer": "^2.3", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^6 || ^7 || ^8", - "psalm/phar": "^3.11.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php" - ], - "psr-4": { - "Amp\\ByteStream\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "http://amphp.org/byte-stream", - "keywords": [ - "amp", - "amphp", - "async", - "io", - "non-blocking", - "stream" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2021-03-30T17:13:30+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-01-17T14:14:24+00:00" - }, - { - "name": "composer/pcre", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], - "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.0" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-11-17T09:50:14+00:00" - }, - { - "name": "composer/semver", - "version": "3.3.2", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-04-01T19:23:25+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", - "shasum": "" - }, - "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" - }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-02-25T21:32:43+00:00" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2022-02-04T12:51:07+00:00" - }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "v0.1.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "implementation of xdg base directory specification for php", - "support": { - "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", - "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" - }, - "time": "2019-12-04T15:06:13+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "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" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "felixfbecker/advanced-json-rpc", - "version": "v3.2.1", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "shasum": "" - }, - "require": { - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "php": "^7.1 || ^8.0", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "AdvancedJsonRpc\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "A more advanced JSONRPC implementation", - "support": { - "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", - "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" - }, - "time": "2021-06-11T22:34:44+00:00" - }, - { - "name": "felixfbecker/language-server-protocol", - "version": "v1.5.2", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-language-server-protocol.git", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpstan/phpstan": "*", - "squizlabs/php_codesniffer": "^3.1", - "vimeo/psalm": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "LanguageServerProtocol\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "PHP classes for the Language Server Protocol", - "keywords": [ - "language", - "microsoft", - "php", - "server" - ], - "support": { - "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", - "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2" - }, - "time": "2022-03-02T22:36:06+00:00" - }, - { - "name": "fidry/cpu-core-counter", - "version": "0.4.1", - "source": { - "type": "git", - "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "79261cc280aded96d098e1b0e0ba0c4881b432c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/79261cc280aded96d098e1b0e0ba0c4881b432c2", - "reference": "79261cc280aded96d098e1b0e0ba0c4881b432c2", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "fidry/makefile": "^0.2.0", - "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": "^9.5.26 || ^8.5.31", - "theofidry/php-cs-fixer-config": "^1.0", - "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/0.4.1" - }, - "funding": [ - { - "url": "https://github.com/theofidry", - "type": "github" - } - ], - "time": "2022-12-16T22:01:02+00:00" - }, - { - "name": "laminas/laminas-coding-standard", - "version": "2.5.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-coding-standard.git", - "reference": "c1aaa18a7c860c6932677a3e4ec13161f9fc7d61" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/c1aaa18a7c860c6932677a3e4ec13161f9fc7d61", - "reference": "c1aaa18a7c860c6932677a3e4ec13161f9fc7d61", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", - "php": "^7.4 || ^8.0", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.6", - "webimpress/coding-standard": "^1.2" - }, - "conflict": { - "phpstan/phpdoc-parser": ">=1.6.0" - }, - "type": "phpcodesniffer-standard", - "autoload": { - "psr-4": { - "LaminasCodingStandard\\": "src/LaminasCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Laminas Coding Standard", - "homepage": "https://laminas.dev", - "keywords": [ - "Coding Standard", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-coding-standard/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-coding-standard/issues", - "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", - "source": "https://github.com/laminas/laminas-coding-standard" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-01-05T15:53:40+00:00" - }, - { - "name": "laminas/laminas-crypt", - "version": "3.9.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-crypt.git", - "reference": "56ab1b195dad5456753601ff2e8e3d3fd9392d1a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-crypt/zipball/56ab1b195dad5456753601ff2e8e3d3fd9392d1a", - "reference": "56ab1b195dad5456753601ff2e8e3d3fd9392d1a", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "laminas/laminas-math": "^3.4", - "laminas/laminas-servicemanager": "^3.11.2", - "laminas/laminas-stdlib": "^3.6", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "psr/container": "^1.1" - }, - "conflict": { - "zendframework/zend-crypt": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "^9.5.25" - }, - "suggest": { - "ext-openssl": "Required for most features of Laminas\\Crypt" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Crypt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Strong cryptography tools and password hashing", - "homepage": "https://laminas.dev", - "keywords": [ - "crypt", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-crypt/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-crypt/issues", - "rss": "https://github.com/laminas/laminas-crypt/releases.atom", - "source": "https://github.com/laminas/laminas-crypt" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-16T15:51:01+00:00" - }, - { - "name": "laminas/laminas-db", - "version": "2.16.3", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-db.git", - "reference": "dadd9a19d2f9e89aa59205572b928892b91ff1da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-db/zipball/dadd9a19d2f9e89aa59205572b928892b91ff1da", - "reference": "dadd9a19d2f9e89aa59205572b928892b91ff1da", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.7.1", - "php": "~8.0.0 || ~8.1.0|| ~8.2.0" - }, - "conflict": { - "zendframework/zend-db": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "laminas/laminas-eventmanager": "^3.6.0", - "laminas/laminas-hydrator": "^4.7", - "laminas/laminas-servicemanager": "^3.19.0", - "phpunit/phpunit": "^9.5.25" - }, - "suggest": { - "laminas/laminas-eventmanager": "Laminas\\EventManager component", - "laminas/laminas-hydrator": "(^3.2 || ^4.3) Laminas\\Hydrator component for using HydratingResultSets", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Db", - "config-provider": "Laminas\\Db\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Db\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", - "homepage": "https://laminas.dev", - "keywords": [ - "db", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-db/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-db/issues", - "rss": "https://github.com/laminas/laminas-db/releases.atom", - "source": "https://github.com/laminas/laminas-db" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-12-17T16:31:58+00:00" - }, - { - "name": "laminas/laminas-math", - "version": "3.6.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-math.git", - "reference": "5770fc632a3614f5526632a8b70f41b65130460e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-math/zipball/5770fc632a3614f5526632a8b70f41b65130460e", - "reference": "5770fc632a3614f5526632a8b70f41b65130460e", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-math": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "~9.5.25" - }, - "suggest": { - "ext-bcmath": "If using the bcmath functionality", - "ext-gmp": "If using the gmp functionality" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2.x-dev", - "dev-develop": "3.3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Math\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Create cryptographically secure pseudo-random numbers, and manage big integers", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "math" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-math/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-math/issues", - "rss": "https://github.com/laminas/laminas-math/releases.atom", - "source": "https://github.com/laminas/laminas-math" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-16T14:22:28+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "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" - }, - "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.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "netresearch/jsonmapper", - "version": "v4.1.0", - "source": { - "type": "git", - "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/cfa81ea1d35294d64adb9c68aa4cb9e92400e53f", - "reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", - "squizlabs/php_codesniffer": "~3.5" - }, - "type": "library", - "autoload": { - "psr-0": { - "JsonMapper": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "OSL-3.0" - ], - "authors": [ - { - "name": "Christian Weiske", - "email": "cweiske@cweiske.de", - "homepage": "http://github.com/cweiske/jsonmapper/", - "role": "Developer" - } - ], - "description": "Map nested JSON structures onto PHP classes", - "support": { - "email": "cweiske@cweiske.de", - "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v4.1.0" - }, - "time": "2022-12-08T20:46:14+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.2", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-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/v4.15.2" - }, - "time": "2022-11-12T15:38:23+00:00" - }, - { - "name": "openlss/lib-array2xml", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/nullivex/lib-array2xml.git", - "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", - "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "autoload": { - "psr-0": { - "LSS": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Bryan Tong", - "email": "bryan@nullivex.com", - "homepage": "https://www.nullivex.com" - }, - { - "name": "Tony Butler", - "email": "spudz76@gmail.com", - "homepage": "https://www.nullivex.com" - } - ], - "description": "Array2XML conversion library credit to lalit.org", - "homepage": "https://www.nullivex.com", - "keywords": [ - "array", - "array conversion", - "xml", - "xml conversion" - ], - "support": { - "issues": "https://github.com/nullivex/lib-array2xml/issues", - "source": "https://github.com/nullivex/lib-array2xml/tree/master" - }, - "time": "2019-03-29T20:06:56+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "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.3" - }, - "time": "2021-07-20T11:28:43+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.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "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": "account@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.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "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.6.2" - }, - "time": "2022-10-14T12:47:21+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "981cc368a216c988e862a75e526b6076987d1b50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50", - "reference": "981cc368a216c988e862a75e526b6076987d1b50", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "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/1.5.1" - }, - "time": "2022-05-05T11:32:40+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.21", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "3f893e19712bb0c8bc86665d1562e9fd509c4ef0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/3f893e19712bb0c8bc86665d1562e9fd509c4ef0", - "reference": "3f893e19712bb0c8bc86665d1562e9fd509c4ef0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "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" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.2-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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.21" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-12-14T13:26:54+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-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", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.27", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "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.13", - "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" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.5-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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27" - }, - "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": "2022-12-09T07:31:23+00:00" - }, - { - "name": "psalm/plugin-phpunit", - "version": "0.18.4", - "source": { - "type": "git", - "url": "https://github.com/psalm/psalm-plugin-phpunit.git", - "reference": "e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc", - "reference": "e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc", - "shasum": "" - }, - "require": { - "composer/package-versions-deprecated": "^1.10", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "ext-simplexml": "*", - "php": "^7.1 || ^8.0", - "vimeo/psalm": "dev-master || dev-4.x || ^4.7.1 || ^5@beta || ^5.0" - }, - "conflict": { - "phpunit/phpunit": "<7.5" - }, - "require-dev": { - "codeception/codeception": "^4.0.3", - "php": "^7.3 || ^8.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0", - "squizlabs/php_codesniffer": "^3.3.1", - "weirdan/codeception-psalm-module": "^0.11.0", - "weirdan/prophecy-shim": "^1.0 || ^2.0" - }, - "type": "psalm-plugin", - "extra": { - "psalm": { - "pluginClass": "Psalm\\PhpUnitPlugin\\Plugin" - } - }, - "autoload": { - "psr-4": { - "Psalm\\PhpUnitPlugin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Brown", - "email": "github@muglug.com" - } - ], - "description": "Psalm plugin for PHPUnit", - "support": { - "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", - "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.18.4" - }, - "time": "2022-12-03T07:47:07+00:00" - }, - { - "name": "psr/log", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", - "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.0" - }, - "time": "2021-07-14T16:46:02+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "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": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-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 types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "7.2.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phing/phing": "2.17.3", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.7.1", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2022-05-25T10:58:12+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "symfony/console", - "version": "v6.0.16", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "be294423f337dda97c810733138c0caec1bb0575" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/be294423f337dda97c810733138c0caec1bb0575", - "reference": "be294423f337dda97c810733138c0caec1bb0575", - "shasum": "" - }, - "require": { - "php": ">=8.0.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.4|^6.0" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v6.0.16" - }, - "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": "2022-11-25T18:58:46+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "shasum": "" - }, - "require": { - "php": ">=8.0.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" - }, - "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": "2022-01-02T09:55:41+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v6.0.13", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "3adca49133bd055ebe6011ed1e012be3c908af79" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/3adca49133bd055ebe6011ed1e012be3c908af79", - "reference": "3adca49133bd055ebe6011ed1e012be3c908af79", - "shasum": "" - }, - "require": { - "php": ">=8.0.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.13" - }, - "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": "2022-09-21T20:25:27+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "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/polyfill-php80/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/process", - "version": "v6.0.11", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "44270a08ccb664143dede554ff1c00aaa2247a43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/44270a08ccb664143dede554ff1c00aaa2247a43", - "reference": "44270a08ccb664143dede554ff1c00aaa2247a43", - "shasum": "" - }, - "require": { - "php": ">=8.0.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v6.0.11" - }, - "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": "2022-06-27T17:10:44+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v2.5.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" - }, - "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": "2022-05-30T19:17:29+00:00" - }, - { - "name": "symfony/string", - "version": "v6.0.15", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "51ac0fa0ccf132a00519b87c97e8f775fa14e771" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/51ac0fa0ccf132a00519b87c97e8f775fa14e771", - "reference": "51ac0fa0ccf132a00519b87c97e8f775fa14e771", - "shasum": "" - }, - "require": { - "php": ">=8.0.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.0" - }, - "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.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", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v6.0.15" - }, - "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": "2022-10-10T09:34:08+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "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" - } - ], - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "vimeo/psalm", - "version": "5.2.0", - "source": { - "type": "git", - "url": "https://github.com/vimeo/psalm.git", - "reference": "fb685a16df3050d4c18d8a4100fe83abe6458cba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/fb685a16df3050d4c18d8a4100fe83abe6458cba", - "reference": "fb685a16df3050d4c18d8a4100fe83abe6458cba", - "shasum": "" - }, - "require": { - "amphp/amp": "^2.4.2", - "amphp/byte-stream": "^1.5", - "composer/package-versions-deprecated": "^1.10.0", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^2.0 || ^3.0", - "dnoegel/php-xdg-base-dir": "^0.1.1", - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*", - "felixfbecker/advanced-json-rpc": "^3.1", - "felixfbecker/language-server-protocol": "^1.5.2", - "fidry/cpu-core-counter": "^0.4.0", - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "nikic/php-parser": "^4.13", - "openlss/lib-array2xml": "^1.0", - "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0", - "sebastian/diff": "^4.0", - "symfony/console": "^4.1.6 || ^5.0 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/polyfill-php80": "^1.25" - }, - "provide": { - "psalm/psalm": "self.version" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.4", - "brianium/paratest": "^6.0", - "ext-curl": "*", - "mockery/mockery": "^1.5", - "nunomaduro/mock-final-classes": "^1.1", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpdoc-parser": "^1.6", - "phpunit/phpunit": "^9.5", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.6", - "symfony/process": "^4.4 || ^5.0 || ^6.0" - }, - "suggest": { - "ext-curl": "In order to send data to shepherd", - "ext-igbinary": "^2.0.5 is required, used to serialize caching data" - }, - "bin": [ - "psalm", - "psalm-language-server", - "psalm-plugin", - "psalm-refactor", - "psalter" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev", - "dev-4.x": "4.x-dev", - "dev-3.x": "3.x-dev", - "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psalm\\": "src/Psalm/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthew Brown" - } - ], - "description": "A static analysis tool for finding errors in PHP applications", - "keywords": [ - "code", - "inspection", - "php" - ], - "support": { - "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm/tree/5.2.0" - }, - "time": "2022-12-12T08:18:56+00:00" - }, - { - "name": "webimpress/coding-standard", - "version": "1.2.4", - "source": { - "type": "git", - "url": "https://github.com/webimpress/coding-standard.git", - "reference": "cd0c4b0b97440c337c1f7da17b524674ca2f9ca9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/cd0c4b0b97440c337c1f7da17b524674ca2f9ca9", - "reference": "cd0c4b0b97440c337c1f7da17b524674ca2f9ca9", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.13" - }, - "type": "phpcodesniffer-standard", - "extra": { - "dev-master": "1.2.x-dev", - "dev-develop": "1.3.x-dev" - }, - "autoload": { - "psr-4": { - "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "description": "Webimpress Coding Standard", - "keywords": [ - "Coding Standard", - "PSR-2", - "phpcs", - "psr-12", - "webimpress" - ], - "support": { - "issues": "https://github.com/webimpress/coding-standard/issues", - "source": "https://github.com/webimpress/coding-standard/tree/1.2.4" - }, - "funding": [ - { - "url": "https://github.com/michalbundyra", - "type": "github" - } - ], - "time": "2022-02-15T19:52:12+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "ext-iconv": "*" - }, - "platform-dev": [], - "platform-overrides": { - "php": "8.0.99" - }, - "plugin-api-version": "2.3.0" -} diff --git a/lib/laminas/laminas-mail/src/Address.php b/lib/laminas/laminas-mail/src/Address.php deleted file mode 100644 index c6f3d6d48..000000000 --- a/lib/laminas/laminas-mail/src/Address.php +++ /dev/null @@ -1,171 +0,0 @@ -.*)<(?P[^>]+)>|(?P.+))$/', $address, $matches)) { - throw new Exception\InvalidArgumentException('Invalid address format'); - } - - $name = null; - if (isset($matches['name'])) { - $name = trim($matches['name']); - } - if (empty($name)) { - $name = null; - } - - if (isset($matches['namedEmail'])) { - $email = $matches['namedEmail']; - } - if (isset($matches['email'])) { - $email = $matches['email']; - } - $email = trim($email); - //trim single quotes, because outlook does add single quotes to emails sometimes which is technically not valid - $email = trim($email, '\''); - - return new static($email, $name, $comment); - } - - /** - * Constructor - * - * @param string $email - * @param null|string $name - * @param null|string $comment - * @throws Exception\InvalidArgumentException - */ - public function __construct($email, $name = null, $comment = null) - { - $emailAddressValidator = new EmailAddressValidator(Hostname::ALLOW_DNS | Hostname::ALLOW_LOCAL); - if (! is_string($email) || empty($email)) { - throw new Exception\InvalidArgumentException('Email must be a valid email address'); - } - - if (preg_match("/[\r\n]/", $email)) { - throw new Exception\InvalidArgumentException('CRLF injection detected'); - } - - if (! $emailAddressValidator->isValid($email)) { - $invalidMessages = $emailAddressValidator->getMessages(); - throw new Exception\InvalidArgumentException(array_shift($invalidMessages)); - } - - if (null !== $name) { - if (! is_string($name)) { - throw new Exception\InvalidArgumentException('Name must be a string'); - } - - if (preg_match("/[\r\n]/", $name)) { - throw new Exception\InvalidArgumentException('CRLF injection detected'); - } - - $this->name = $name; - } - - $this->email = $email; - - if (null !== $comment) { - $this->comment = $comment; - } - } - - /** - * Retrieve email - * - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * Retrieve name, if any - * - * @return null|string - */ - public function getName() - { - return $this->name; - } - - /** - * Retrieve comment, if any - * - * @return null|string - */ - public function getComment() - { - return $this->comment; - } - - /** - * String representation of address - * - * @return string - */ - public function toString() - { - $string = sprintf('<%s>', $this->getEmail()); - $name = $this->constructName(); - if (null === $name) { - return $string; - } - - return sprintf('%s %s', $name, $string); - } - - /** - * Constructs the name string - * - * If a comment is present, appends the comment (commented using parens) to - * the name before returning it; otherwise, returns just the name. - * - * @return null|string - */ - private function constructName() - { - $name = $this->getName(); - $comment = $this->getComment(); - - if ($comment === null || $comment === '') { - return $name; - } - - $string = sprintf('%s (%s)', $name, $comment); - return trim($string); - } -} diff --git a/lib/laminas/laminas-mail/src/Address/AddressInterface.php b/lib/laminas/laminas-mail/src/Address/AddressInterface.php deleted file mode 100644 index c75c6f75b..000000000 --- a/lib/laminas/laminas-mail/src/Address/AddressInterface.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @final - */ -class AddressList implements Countable, Iterator -{ - /** - * List of Address objects we're managing - * - * @var array - */ - protected $addresses = []; - - /** - * Add an address to the list - * - * @param string|AddressInterface $emailOrAddress - * @param null|string $name - * @throws Exception\InvalidArgumentException - * @return $this - */ - public function add($emailOrAddress, $name = null) - { - if (is_string($emailOrAddress)) { - $emailOrAddress = $this->createAddress($emailOrAddress, $name); - } - - if (! $emailOrAddress instanceof AddressInterface) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects an email address or %s\Address object as its first argument; received "%s"', - __METHOD__, - __NAMESPACE__, - is_object($emailOrAddress) ? $emailOrAddress::class : gettype($emailOrAddress) - )); - } - - $email = strtolower($emailOrAddress->getEmail()); - if ($this->has($email)) { - return $this; - } - - $this->addresses[$email] = $emailOrAddress; - return $this; - } - - /** - * Add many addresses at once - * - * If an email key is provided, it will be used as the email, and the value - * as the name. Otherwise, the value is passed as the sole argument to add(), - * and, as such, can be either email strings or Address\AddressInterface objects. - * - * @param array $addresses - * @throws Exception\RuntimeException - * @return $this - */ - public function addMany(array $addresses) - { - foreach ($addresses as $key => $value) { - if (is_int($key) || is_numeric($key)) { - $this->add($value); - continue; - } - - if (! is_string($key)) { - throw new Exception\RuntimeException(sprintf( - 'Invalid key type in provided addresses array ("%s")', - is_object($key) ? $key::class : var_export($key, true) - )); - } - - $this->add($key, $value); - } - return $this; - } - - /** - * Add an address to the list from any valid string format, such as - * - "Laminas Dev" - * - dev@laminas.com - * - * @param string $address - * @param null|string $comment Comment associated with the address, if any. - * @throws Exception\InvalidArgumentException - * @return $this - */ - public function addFromString($address, $comment = null) - { - $this->add(Address::fromString($address, $comment)); - return $this; - } - - /** - * Merge another address list into this one - * - * @return $this - */ - public function merge(self $addressList) - { - foreach ($addressList as $address) { - $this->add($address); - } - return $this; - } - - /** - * Does the email exist in this list? - * - * @param string $email - * @return bool - */ - public function has($email) - { - $email = strtolower($email); - return isset($this->addresses[$email]); - } - - /** - * Get an address by email - * - * @param string $email - * @return false|AddressInterface - */ - public function get($email) - { - $email = strtolower($email); - if (! isset($this->addresses[$email])) { - return false; - } - - return $this->addresses[$email]; - } - - /** - * Delete an address from the list - * - * @param string $email - * @return bool - */ - public function delete($email) - { - $email = strtolower($email); - if (! isset($this->addresses[$email])) { - return false; - } - - unset($this->addresses[$email]); - return true; - } - - /** - * Return count of addresses - * - * @return int - */ - #[ReturnTypeWillChange] - public function count() - { - return count($this->addresses); - } - - /** - * Rewind iterator - * - * @see addresses - * - * @return false|AddressInterface the value of the first addresses element, or false if the addresses is - * empty. - */ - #[ReturnTypeWillChange] - public function rewind() - { - return reset($this->addresses); - } - - /** - * Return current item in iteration - * - * @return AddressInterface - */ - #[ReturnTypeWillChange] - public function current() - { - return current($this->addresses); - } - - /** - * Return key of current item of iteration - * - * @return string - */ - #[ReturnTypeWillChange] - public function key() - { - return key($this->addresses); - } - - /** - * Move to next item - * - * @see addresses - * - * @return false|AddressInterface the addresses value in the next place that's pointed to by the - * internal array pointer, or false if there are no more elements. - */ - #[ReturnTypeWillChange] - public function next() - { - return next($this->addresses); - } - - /** - * Is the current item of iteration valid? - * - * @return bool - */ - #[ReturnTypeWillChange] - public function valid() - { - $key = key($this->addresses); - return $key !== null && $key !== false; - } - - /** - * Create an address object - * - * @param string $email - * @param string|null $name - * @return Address - */ - protected function createAddress($email, $name) - { - return new Address($email, $name); - } -} diff --git a/lib/laminas/laminas-mail/src/ConfigProvider.php b/lib/laminas/laminas-mail/src/ConfigProvider.php deleted file mode 100644 index 5c79a4cf0..000000000 --- a/lib/laminas/laminas-mail/src/ConfigProvider.php +++ /dev/null @@ -1,36 +0,0 @@ - $this->getDependencyConfig(), - ]; - } - - /** - * Retrieve dependency settings for laminas-mail package. - * - * @return array - */ - public function getDependencyConfig() - { - return [ - // Legacy Zend Framework aliases - 'aliases' => [ - 'Zend\Mail\Protocol\SmtpPluginManager' => Protocol\SmtpPluginManager::class, - ], - 'factories' => [ - Protocol\SmtpPluginManager::class => Protocol\SmtpPluginManagerFactory::class, - ], - ]; - } -} diff --git a/lib/laminas/laminas-mail/src/Exception/BadMethodCallException.php b/lib/laminas/laminas-mail/src/Exception/BadMethodCallException.php deleted file mode 100644 index 4020cc891..000000000 --- a/lib/laminas/laminas-mail/src/Exception/BadMethodCallException.php +++ /dev/null @@ -1,11 +0,0 @@ - 'empty label', - IDNA_ERROR_LABEL_TOO_LONG => 'label too long', - IDNA_ERROR_DOMAIN_NAME_TOO_LONG => 'domain name too long', - IDNA_ERROR_LEADING_HYPHEN => 'leading hyphen', - IDNA_ERROR_TRAILING_HYPHEN => 'trailing hyphen', - IDNA_ERROR_HYPHEN_3_4 => 'consecutive hyphens', - IDNA_ERROR_LEADING_COMBINING_MARK => 'leading combining mark', - IDNA_ERROR_DISALLOWED => 'disallowed', - IDNA_ERROR_PUNYCODE => 'invalid punycode encoding', - IDNA_ERROR_LABEL_HAS_DOT => 'has dot', - IDNA_ERROR_INVALID_ACE_LABEL => 'label not in ASCII encoding', - IDNA_ERROR_BIDI => 'fails bidirectional criteria', - IDNA_ERROR_CONTEXTJ => 'one or more characters fail CONTEXTJ rule', - ]; - - /** @var AddressList */ - protected $addressList; - - /** @var string Normalized field name */ - protected $fieldName; - - /** - * Header encoding - * - * @var string - */ - protected $encoding = 'ASCII'; - - /** @var string lower case field name */ - protected static $type; - - /** @var string[] lower case aliases for the field name */ - protected static $typeAliases = []; - - /** - * @param string $headerLine - * @return static - */ - public static function fromString($headerLine) - { - [$fieldName, $fieldValue] = GenericHeader::splitHeaderLine($headerLine); - if ((strtolower($fieldName) !== static::$type) && ! in_array(strtolower($fieldName), static::$typeAliases)) { - throw new Exception\InvalidArgumentException(sprintf( - 'Invalid header line for "%s" string', - self::class - )); - } - - // split value on "," - $fieldValue = str_replace(Headers::FOLDING, ' ', $fieldValue); - $fieldValue = preg_replace('/[^:]+:([^;]*);/', '$1,', $fieldValue); - $values = ListParser::parse($fieldValue); - - $wasEncoded = false; - $addresses = array_map( - static function ($value) use (&$wasEncoded): ?Address { - $decodedValue = HeaderWrap::mimeDecodeValue($value); - $wasEncoded = $wasEncoded || ($decodedValue !== $value); - $value = trim($decodedValue); - $comments = self::getComments($value); - $value = self::stripComments($value); - $value = preg_replace( - [ - '#(?setEncoding('UTF-8'); - } - - /** @var AddressList $addressList */ - $addressList = $header->getAddressList(); - foreach ($addresses as $address) { - $addressList->add($address); - } - - return $header; - } - - /** - * @return string - */ - public function getFieldName() - { - return $this->fieldName; - } - - /** - * Safely convert UTF-8 encoded domain name to ASCII - * - * @param string $domainName the UTF-8 encoded email - */ - protected function idnToAscii($domainName): string - { - /** @psalm-var string|false $ascii */ - $ascii = idn_to_ascii($domainName, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, $conversionInfo); - if (is_string($ascii)) { - return $ascii; - } - - $messages = []; - assert(is_array($conversionInfo)); - /* @psalm-var array{errors: numeric-string} $conversionInfo */ - $errors = (int) $conversionInfo['errors']; - - foreach (self::IDNA_ERROR_MAP as $flag => $message) { - if (($flag & $errors) === $flag) { - $messages[] = $message; - } - } - - throw new RuntimeException(sprintf( - 'Failed encoding domain due to errors: %s', - implode(', ', $messages) - )); - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - $emails = []; - $encoding = $this->getEncoding(); - - foreach ($this->getAddressList() as $address) { - $email = $address->getEmail(); - $name = $address->getName(); - - // quote $name if value requires so - if (! empty($name) && (str_contains($name, ',') || str_contains($name, ';'))) { - // FIXME: what if name contains double quote? - $name = sprintf('"%s"', $name); - } - - if ( - $format === HeaderInterface::FORMAT_ENCODED - && 'ASCII' !== $encoding - ) { - if (! empty($name)) { - $name = HeaderWrap::mimeEncodeValue($name, $encoding); - } - - if (preg_match('/^(.+)@([^@]+)$/', $email, $matches)) { - $localPart = $matches[1]; - $hostname = $this->idnToAscii($matches[2]); - $email = sprintf('%s@%s', $localPart, $hostname); - } - } - - if (empty($name)) { - $emails[] = $email; - } else { - $emails[] = sprintf('%s <%s>', $name, $email); - } - } - - // Ensure the values are valid before sending them. - if ($format !== HeaderInterface::FORMAT_RAW) { - foreach ($emails as $email) { - HeaderValue::assertValid($email); - } - } - - return implode(',' . Headers::FOLDING, $emails); - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - $this->encoding = $encoding; - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Set address list for this header - */ - public function setAddressList(AddressList $addressList) - { - $this->addressList = $addressList; - } - - /** - * Get address list managed by this header - * - * @return AddressList - */ - public function getAddressList() - { - if (null === $this->addressList) { - $this->setAddressList(new AddressList()); - } - return $this->addressList; - } - - /** - * @return string - */ - public function toString() - { - $name = $this->getFieldName(); - $value = $this->getFieldValue(HeaderInterface::FORMAT_ENCODED); - return empty($value) ? '' : sprintf('%s: %s', $name, $value); - } - - /** - * Retrieve comments from value, if any. - * - * Supposed to be private, protected as a workaround for PHP bug 68194 - * - * @param string $value - * @return string - */ - protected static function getComments($value) - { - $matches = []; - preg_match_all( - '/\\( - (?P( - \\\\.| - [^\\\\)] - )+) - \\)/x', - $value, - $matches - ); - return isset($matches['comment']) ? implode(', ', $matches['comment']) : ''; - } - - /** - * Strip all comments from value, if any. - * - * Supposed to be private, protected as a workaround for PHP bug 68194 - * - * @param string $value - * @return string - */ - protected static function stripComments($value) - { - return preg_replace( - '/\\( - ( - \\\\.| - [^\\\\)] - )+ - \\)/x', - '', - $value - ); - } -} diff --git a/lib/laminas/laminas-mail/src/Header/Bcc.php b/lib/laminas/laminas-mail/src/Header/Bcc.php deleted file mode 100644 index 9b37e157f..000000000 --- a/lib/laminas/laminas-mail/src/Header/Bcc.php +++ /dev/null @@ -1,12 +0,0 @@ -setDisposition($parts[0]); - - if (isset($parts[1])) { - $values = ListParser::parse(trim($parts[1]), [';', '=']); - $length = count($values); - $continuedValues = []; - - for ($i = 0; $i < $length; $i += 2) { - $value = $values[$i + 1]; - $value = trim($value, "'\" \t\n\r\0\x0B"); - $name = trim($values[$i], "'\" \t\n\r\0\x0B"); - - if (strpos($name, '*')) { - [$name, $count] = explode('*', $name); - // allow optional count: - // Content-Disposition: attachment; filename*=UTF-8''%64%61%61%6D%69%2D%6D%C3%B5%72%76%2E%6A%70%67 - if ($count === "") { - $count = 0; - } - - if (! is_numeric($count)) { - $type = gettype($count); - $value = var_export($count, true); - throw new Exception\InvalidArgumentException(sprintf( - "Invalid header line for Content-Disposition string" - . " - count expected to be numeric, got %s with value %s", - $type, - $value - )); - } - if (! isset($continuedValues[$name])) { - $continuedValues[$name] = []; - } - $continuedValues[$name][$count] = $value; - } else { - $header->setParameter($name, $value); - } - } - - foreach ($continuedValues as $name => $values) { - $value = ''; - for ($i = 0, $iMax = count($values); $i < $iMax; $i++) { - if (! isset($values[$i])) { - throw new Exception\InvalidArgumentException( - 'Invalid header line for Content-Disposition string - incomplete continuation' - . '; HeaderLine: ' . $headerLine - ); - } - $value .= $values[$i]; - } - $header->setParameter($name, $value); - } - } - - return $header; - } - - /** - * @inheritDoc - */ - public function getFieldName() - { - return 'Content-Disposition'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - $result = $this->disposition; - if (empty($this->parameters)) { - return $result; - } - - foreach ($this->parameters as $attribute => $value) { - $valueIsEncoded = false; - if (HeaderInterface::FORMAT_ENCODED === $format && ! Mime::isPrintable($value)) { - $value = $this->getEncodedValue($value); - $valueIsEncoded = true; - } - - $line = sprintf('%s="%s"', $attribute, $value); - - if (strlen($line) < self::MAX_PARAMETER_LENGTH) { - $lines = explode(Headers::FOLDING, $result); - - if (count($lines) === 1) { - $existingLineLength = strlen('Content-Disposition: ' . $result); - } else { - $existingLineLength = 1 + strlen($lines[count($lines) - 1]); - } - - if ((2 + $existingLineLength + strlen($line)) <= self::MAX_PARAMETER_LENGTH) { - $result .= '; ' . $line; - } else { - $result .= ';' . Headers::FOLDING . $line; - } - } else { - // Use 'continuation' per RFC 2231 - if ($valueIsEncoded) { - $value = HeaderWrap::mimeDecodeValue($value); - } - - $i = 0; - $fullLength = mb_strlen($value, 'UTF-8'); - while ($fullLength > 0) { - $attributePart = $attribute . '*' . $i++ . '="'; - $attLen = mb_strlen($attributePart, 'UTF-8'); - - $subPos = 1; - $valuePart = ''; - while ($subPos <= $fullLength) { - $sub = mb_substr($value, 0, $subPos, 'UTF-8'); - if ($valueIsEncoded) { - $sub = $this->getEncodedValue($sub); - } - if ($attLen + mb_strlen($sub, 'UTF-8') >= self::MAX_PARAMETER_LENGTH) { - $subPos--; - break; - } - $subPos++; - $valuePart = $sub; - } - - $value = mb_substr($value, $subPos, null, 'UTF-8'); - $fullLength = mb_strlen($value, 'UTF-8'); - $result .= ';' . Headers::FOLDING . $attributePart . $valuePart . '"'; - } - } - } - - return $result; - } - - /** - * @param string $value - * @return string - */ - protected function getEncodedValue($value) - { - $configuredEncoding = $this->encoding; - $this->encoding = 'UTF-8'; - $value = HeaderWrap::wrap($value, $this); - $this->encoding = $configuredEncoding; - return $value; - } - - /** - * @inheritDoc - */ - public function setEncoding($encoding) - { - $this->encoding = $encoding; - return $this; - } - - /** - * @inheritDoc - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * @inheritDoc - */ - public function toString() - { - return 'Content-Disposition: ' . $this->getFieldValue(HeaderInterface::FORMAT_ENCODED); - } - - /** - * Set the content disposition - * Expected values include 'inline', 'attachment' - * - * @param string $disposition - * @return ContentDisposition - */ - public function setDisposition($disposition) - { - $this->disposition = strtolower($disposition); - return $this; - } - - /** - * Retrieve the content disposition - * - * @return string - */ - public function getDisposition() - { - return $this->disposition; - } - - /** - * Add a parameter pair - * - * @param string $name - * @param string $value - * @return ContentDisposition - */ - public function setParameter($name, $value) - { - $name = strtolower($name); - - if (! HeaderValue::isValid($name)) { - throw new Exception\InvalidArgumentException( - 'Invalid content-disposition parameter name detected' - ); - } - // '5' here is for the quotes & equal sign in `name="value"`, - // and the space & semicolon for line folding - if ((strlen($name) + 5) >= self::MAX_PARAMETER_LENGTH) { - throw new Exception\InvalidArgumentException( - 'Invalid content-disposition parameter name detected (too long)' - ); - } - - $this->parameters[$name] = $value; - return $this; - } - - /** - * Get all parameters - * - * @return array - */ - public function getParameters() - { - return $this->parameters; - } - - /** - * Get a parameter by name - * - * @param string $name - * @return null|string - */ - public function getParameter($name) - { - $name = strtolower($name); - if (isset($this->parameters[$name])) { - return $this->parameters[$name]; - } - return null; - } - - /** - * Remove a named parameter - * - * @param string $name - * @return bool - */ - public function removeParameter($name) - { - $name = strtolower($name); - if (isset($this->parameters[$name])) { - unset($this->parameters[$name]); - return true; - } - return false; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/ContentTransferEncoding.php b/lib/laminas/laminas-mail/src/Header/ContentTransferEncoding.php deleted file mode 100644 index 6873f05ae..000000000 --- a/lib/laminas/laminas-mail/src/Header/ContentTransferEncoding.php +++ /dev/null @@ -1,135 +0,0 @@ -setTransferEncoding($value); - - return $header; - } - - /** - * @return string - */ - public function getFieldName() - { - return 'Content-Transfer-Encoding'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - return $this->transferEncoding; - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - // Header must be always in US-ASCII - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - return 'ASCII'; - } - - /** - * @return string - */ - public function toString() - { - return 'Content-Transfer-Encoding: ' . $this->getFieldValue(); - } - - /** - * Set the content transfer encoding - * - * @param string $transferEncoding - * @throws Exception\InvalidArgumentException - * @return $this - */ - public function setTransferEncoding($transferEncoding) - { - // Per RFC 1521, the value of the header is not case sensitive - $transferEncoding = strtolower($transferEncoding); - - if (! in_array($transferEncoding, static::$allowedTransferEncodings)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects one of "' . implode(', ', static::$allowedTransferEncodings) . '"; received "%s"', - __METHOD__, - (string) $transferEncoding - )); - } - $this->transferEncoding = $transferEncoding; - return $this; - } - - /** - * Retrieve the content transfer encoding - * - * @return string - */ - public function getTransferEncoding() - { - return $this->transferEncoding; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/ContentType.php b/lib/laminas/laminas-mail/src/Header/ContentType.php deleted file mode 100644 index 4ed083b43..000000000 --- a/lib/laminas/laminas-mail/src/Header/ContentType.php +++ /dev/null @@ -1,223 +0,0 @@ -setType($parts[0]); - - if (isset($parts[1])) { - $values = ListParser::parse(trim($parts[1]), [';', '=']); - $length = count($values); - - for ($i = 0; $i < $length; $i += 2) { - $value = $values[$i + 1]; - $value = trim($value, "'\" \t\n\r\0\x0B"); - $header->addParameter($values[$i], $value); - } - } - - return $header; - } - - /** - * @return string - */ - public function getFieldName() - { - return 'Content-Type'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - $prepared = $this->type; - if (empty($this->parameters)) { - return $prepared; - } - - $values = [$prepared]; - foreach ($this->parameters as $attribute => $value) { - if (HeaderInterface::FORMAT_ENCODED === $format && ! Mime::isPrintable($value)) { - $this->encoding = 'UTF-8'; - $value = HeaderWrap::wrap($value, $this); - $this->encoding = 'ASCII'; - } - - $values[] = sprintf('%s="%s"', $attribute, $value); - } - - return implode(';' . Headers::FOLDING, $values); - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - $this->encoding = $encoding; - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * @return string - */ - public function toString() - { - return 'Content-Type: ' . $this->getFieldValue(HeaderInterface::FORMAT_ENCODED); - } - - /** - * Set the content type - * - * @param string $type - * @throws Exception\InvalidArgumentException - * @return ContentType - */ - public function setType($type) - { - if (! preg_match('/^[a-z-]+\/[a-z0-9.+-]+$/i', $type)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects a value in the format "type/subtype"; received "%s"', - __METHOD__, - (string) $type - )); - } - $this->type = $type; - return $this; - } - - /** - * Retrieve the content type - * - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * Add a parameter pair - * - * @param string $name - * @param string $value - * @return ContentType - * @throws Exception\InvalidArgumentException For parameter names that do not follow RFC 2822. - * @throws Exception\InvalidArgumentException For parameter values that do not follow RFC 2822. - */ - public function addParameter($name, $value) - { - $name = trim(strtolower($name)); - $value = (string) $value; - - if (! HeaderValue::isValid($name)) { - throw new Exception\InvalidArgumentException('Invalid content-type parameter name detected'); - } - if (! HeaderWrap::canBeEncoded($value)) { - throw new Exception\InvalidArgumentException( - 'Parameter value must be composed of printable US-ASCII or UTF-8 characters.' - ); - } - - $this->parameters[$name] = $value; - return $this; - } - - /** - * Get all parameters - * - * @return array - */ - public function getParameters() - { - return $this->parameters; - } - - /** - * Get a parameter by name - * - * @param string $name - * @return null|string - */ - public function getParameter($name) - { - $name = strtolower($name); - if (isset($this->parameters[$name])) { - return $this->parameters[$name]; - } - - return null; - } - - /** - * Remove a named parameter - * - * @param string $name - * @return bool - */ - public function removeParameter($name) - { - $name = strtolower($name); - if (isset($this->parameters[$name])) { - unset($this->parameters[$name]); - return true; - } - return false; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/Date.php b/lib/laminas/laminas-mail/src/Header/Date.php deleted file mode 100644 index 32bfef919..000000000 --- a/lib/laminas/laminas-mail/src/Header/Date.php +++ /dev/null @@ -1,84 +0,0 @@ -value = $value; - } - - /** - * @return string - */ - public function getFieldName() - { - return 'Date'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - return $this->value; - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - // This header must be always in US-ASCII - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - return 'ASCII'; - } - - /** - * @return string - */ - public function toString() - { - return 'Date: ' . $this->getFieldValue(); - } -} diff --git a/lib/laminas/laminas-mail/src/Header/Exception/BadMethodCallException.php b/lib/laminas/laminas-mail/src/Header/Exception/BadMethodCallException.php deleted file mode 100644 index 7506af5f4..000000000 --- a/lib/laminas/laminas-mail/src/Header/Exception/BadMethodCallException.php +++ /dev/null @@ -1,9 +0,0 @@ -setFieldName($fieldName); - - if ($fieldValue !== null) { - $this->setFieldValue($fieldValue); - } - } - - /** - * Set header name - * - * @param string $fieldName - * @return GenericHeader - * @throws Exception\InvalidArgumentException; - */ - public function setFieldName($fieldName) - { - if (! is_string($fieldName) || empty($fieldName)) { - throw new InvalidArgumentException('Header name must be a string'); - } - - // Pre-filter to normalize valid characters, change underscore to dash - $fieldName = str_replace(' ', '-', ucwords(str_replace(['_', '-'], ' ', $fieldName))); - - if (! HeaderName::isValid($fieldName)) { - throw new InvalidArgumentException( - 'Header name must be composed of printable US-ASCII characters, except colon.' - ); - } - - $this->fieldName = $fieldName; - return $this; - } - - /** - * @return string - */ - public function getFieldName() - { - return $this->fieldName; - } - - /** - * Set header value - * - * @param string $fieldValue - * @return GenericHeader - * @throws Exception\InvalidArgumentException; - */ - public function setFieldValue($fieldValue) - { - $fieldValue = (string) $fieldValue; - - if (! HeaderWrap::canBeEncoded($fieldValue)) { - throw new InvalidArgumentException( - 'Header value must be composed of printable US-ASCII characters and valid folding sequences.' - ); - } - - $this->fieldValue = $fieldValue; - $this->encoding = null; - - return $this; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - if (HeaderInterface::FORMAT_ENCODED === $format) { - return HeaderWrap::wrap($this->fieldValue, $this); - } - - return $this->fieldValue; - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - if ($encoding === $this->encoding) { - return $this; - } - - if ($encoding === null) { - $this->encoding = null; - return $this; - } - - $encoding = strtoupper($encoding); - if ($encoding === 'UTF-8') { - $this->encoding = $encoding; - return $this; - } - - if ($encoding === 'ASCII' && Mime::isPrintable($this->fieldValue)) { - $this->encoding = $encoding; - return $this; - } - - $this->encoding = null; - - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - if (! $this->encoding) { - $this->encoding = Mime::isPrintable($this->fieldValue) ? 'ASCII' : 'UTF-8'; - } - - return $this->encoding; - } - - /** - * @return string - */ - public function toString() - { - $name = $this->getFieldName(); - if (empty($name)) { - throw new Exception\RuntimeException('Header name is not set, use setFieldName()'); - } - $value = $this->getFieldValue(HeaderInterface::FORMAT_ENCODED); - - return $name . ': ' . $value; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/GenericMultiHeader.php b/lib/laminas/laminas-mail/src/Header/GenericMultiHeader.php deleted file mode 100644 index 452c6336f..000000000 --- a/lib/laminas/laminas-mail/src/Header/GenericMultiHeader.php +++ /dev/null @@ -1,57 +0,0 @@ -getFieldName(); - $values = [$this->getFieldValue(HeaderInterface::FORMAT_ENCODED)]; - - foreach ($headers as $header) { - if (! $header instanceof static) { - throw new Exception\InvalidArgumentException( - 'This method toStringMultipleHeaders was expecting an array of headers of the same type' - ); - } - $values[] = $header->getFieldValue(HeaderInterface::FORMAT_ENCODED); - } - - return $name . ': ' . implode(',', $values); - } -} diff --git a/lib/laminas/laminas-mail/src/Header/HeaderInterface.php b/lib/laminas/laminas-mail/src/Header/HeaderInterface.php deleted file mode 100644 index cb93e3df8..000000000 --- a/lib/laminas/laminas-mail/src/Header/HeaderInterface.php +++ /dev/null @@ -1,70 +0,0 @@ - Bcc::class, - 'cc' => Cc::class, - 'contentdisposition' => ContentDisposition::class, - 'content_disposition' => ContentDisposition::class, - 'content-disposition' => ContentDisposition::class, - 'contenttype' => ContentType::class, - 'content_type' => ContentType::class, - 'content-type' => ContentType::class, - 'contenttransferencoding' => ContentTransferEncoding::class, - 'content_transfer_encoding' => ContentTransferEncoding::class, - 'content-transfer-encoding' => ContentTransferEncoding::class, - 'date' => Date::class, - 'from' => From::class, - 'in-reply-to' => InReplyTo::class, - 'message-id' => MessageId::class, - 'mimeversion' => MimeVersion::class, - 'mime_version' => MimeVersion::class, - 'mime-version' => MimeVersion::class, - 'received' => Received::class, - 'references' => References::class, - 'replyto' => ReplyTo::class, - 'reply_to' => ReplyTo::class, - 'reply-to' => ReplyTo::class, - 'sender' => Sender::class, - 'subject' => Subject::class, - 'to' => To::class, - ]; -} diff --git a/lib/laminas/laminas-mail/src/Header/HeaderLocator.php b/lib/laminas/laminas-mail/src/Header/HeaderLocator.php deleted file mode 100644 index aea477595..000000000 --- a/lib/laminas/laminas-mail/src/Header/HeaderLocator.php +++ /dev/null @@ -1,69 +0,0 @@ - Bcc::class, - 'cc' => Cc::class, - 'contentdisposition' => ContentDisposition::class, - 'content_disposition' => ContentDisposition::class, - 'content-disposition' => ContentDisposition::class, - 'contenttype' => ContentType::class, - 'content_type' => ContentType::class, - 'content-type' => ContentType::class, - 'contenttransferencoding' => ContentTransferEncoding::class, - 'content_transfer_encoding' => ContentTransferEncoding::class, - 'content-transfer-encoding' => ContentTransferEncoding::class, - 'date' => Date::class, - 'from' => From::class, - 'in-reply-to' => InReplyTo::class, - 'message-id' => MessageId::class, - 'mimeversion' => MimeVersion::class, - 'mime_version' => MimeVersion::class, - 'mime-version' => MimeVersion::class, - 'received' => Received::class, - 'references' => References::class, - 'replyto' => ReplyTo::class, - 'reply_to' => ReplyTo::class, - 'reply-to' => ReplyTo::class, - 'sender' => Sender::class, - 'subject' => Subject::class, - 'to' => To::class, - ]; - - public function get(string $name, ?string $default = null): ?string - { - $name = $this->normalizeName($name); - return $this->plugins[$name] ?? $default; - } - - public function has(string $name): bool - { - return isset($this->plugins[$this->normalizeName($name)]); - } - - public function add(string $name, string $class): void - { - $this->plugins[$this->normalizeName($name)] = $class; - } - - public function remove(string $name): void - { - unset($this->plugins[$this->normalizeName($name)]); - } - - private function normalizeName(string $name): string - { - return strtolower($name); - } -} diff --git a/lib/laminas/laminas-mail/src/Header/HeaderLocatorInterface.php b/lib/laminas/laminas-mail/src/Header/HeaderLocatorInterface.php deleted file mode 100644 index 28a93dc95..000000000 --- a/lib/laminas/laminas-mail/src/Header/HeaderLocatorInterface.php +++ /dev/null @@ -1,19 +0,0 @@ - 32 && $ord < 127 && $ord !== 58) { - $result .= $name[$i]; - } - } - return $result; - } - - /** - * Determine if the header name contains any invalid characters. - * - * @param string $name - * @return bool - */ - public static function isValid($name) - { - $tot = strlen($name); - for ($i = 0; $i < $tot; $i += 1) { - $ord = ord($name[$i]); - if ($ord < 33 || $ord > 126 || $ord === 58) { - return false; - } - } - return true; - } - - /** - * Assert that the header name is valid. - * - * Raises an exception if invalid. - * - * @param string $name - * @throws Exception\RuntimeException - * @return void - */ - public static function assertValid($name) - { - if (! self::isValid($name)) { - throw new Exception\RuntimeException('Invalid header name detected'); - } - } -} diff --git a/lib/laminas/laminas-mail/src/Header/HeaderValue.php b/lib/laminas/laminas-mail/src/Header/HeaderValue.php deleted file mode 100644 index 2a2e1028a..000000000 --- a/lib/laminas/laminas-mail/src/Header/HeaderValue.php +++ /dev/null @@ -1,116 +0,0 @@ - 127) { - continue; - } - - if ($ord === 13) { - if ($i + 2 >= $total) { - continue; - } - - $lf = ord($value[$i + 1]); - $sp = ord($value[$i + 2]); - - if ($lf !== 10 || $sp !== 32) { - continue; - } - - $result .= "\r\n "; - $i += 2; - continue; - } - - $result .= $value[$i]; - } - - return $result; - } - - /** - * Determine if the header value contains any invalid characters. - * - * @see http://www.rfc-base.org/txt/rfc-2822.txt (section 2.2) - * - * @param string $value - * @return bool - */ - public static function isValid($value) - { - $total = strlen($value); - for ($i = 0; $i < $total; $i += 1) { - $ord = ord($value[$i]); - - // bare LF means we aren't valid - if ($ord === 10 || $ord > 127) { - return false; - } - - if ($ord === 13) { - if ($i + 2 >= $total) { - return false; - } - - $lf = ord($value[$i + 1]); - $sp = ord($value[$i + 2]); - - if ($lf !== 10 || ! in_array($sp, [9, 32], true)) { - return false; - } - - // skip over the LF following this - $i += 2; - } - } - - return true; - } - - /** - * Assert that the header value is valid. - * - * Raises an exception if invalid. - * - * @param string $value - * @throws Exception\RuntimeException - * @return void - */ - public static function assertValid($value) - { - if (! self::isValid($value)) { - throw new Exception\RuntimeException('Invalid header value detected'); - } - } -} diff --git a/lib/laminas/laminas-mail/src/Header/HeaderWrap.php b/lib/laminas/laminas-mail/src/Header/HeaderWrap.php deleted file mode 100644 index b63feb1a9..000000000 --- a/lib/laminas/laminas-mail/src/Header/HeaderWrap.php +++ /dev/null @@ -1,186 +0,0 @@ -getFieldName() . ': '); - $encoding = $header->getEncoding(); - - if ($encoding == 'ASCII') { - /* - * Before folding the header line, it is necessary to calculate the length of the - * entire header (including the name and colon). We need to put a stub at the - * beginning of the value so that the folding is performed correctly. - */ - $headerLine = str_pad('0', $headerNameColonSize, '0') . $value; - $foldedHeaderLine = wordwrap($headerLine, 78, Headers::FOLDING); - - // Remove the stub and return the header folded value. - return substr($foldedHeaderLine, $headerNameColonSize); - } - - return static::mimeEncodeValue($value, $encoding, 78, $headerNameColonSize); - } - - /** - * Wrap a structured header line - * - * @param string $value - * @return string - */ - protected static function wrapStructuredHeader($value, StructuredInterface $header) - { - $delimiter = $header->getDelimiter(); - - $length = strlen($value); - $lines = []; - $temp = ''; - for ($i = 0; $i < $length; $i++) { - $temp .= $value[$i]; - if ($value[$i] == $delimiter) { - $lines[] = $temp; - $temp = ''; - } - } - return implode(Headers::FOLDING, $lines); - } - - /** - * MIME-encode a value - * - * Performs quoted-printable encoding on a value, setting maximum - * line-length to 998. - * - * @param string $value - * @param string $encoding - * @param int $lineLength Maximum line-length, by default 998 - * @param positive-int|0 $firstLineGapSize When folding a line, it is necessary to calculate - * the length of the entire line (together with the - * header name). Therefore, you can specify the header - * name and colon length in this argument to fold the - * string properly. - * @return string Returns the mime encode value without the last line ending - */ - public static function mimeEncodeValue($value, $encoding, $lineLength = 998, $firstLineGapSize = 0) - { - return Mime::encodeQuotedPrintableHeader($value, $encoding, $lineLength, Headers::EOL, $firstLineGapSize); - } - - /** - * MIME-decode a value - * - * Performs quoted-printable decoding on a value. - * - * @param string $value - * @return string Returns the mime encode value without the last line ending - */ - public static function mimeDecodeValue($value) - { - // unfold first, because iconv_mime_decode is discarding "\n" with no apparent reason - // making the resulting value no longer valid. - - // see https://tools.ietf.org/html/rfc2822#section-2.2.3 about unfolding - $parts = explode(Headers::FOLDING, $value); - $value = implode(' ', $parts); - - $decodedValue = iconv_mime_decode($value, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); - - // imap (unlike iconv) can handle multibyte headers which are splitted across multiple line - if (self::isNotDecoded($value, $decodedValue) && extension_loaded('imap')) { - return array_reduce( - imap_mime_header_decode(imap_utf8($value)), - static fn($accumulator, $headerPart) => $accumulator . $headerPart->text, - '' - ); - } - - return $decodedValue; - } - - private static function isNotDecoded(string $originalValue, string $value): bool - { - return str_starts_with($value, '=?') - && strlen($value) - 2 === strpos($value, '?=') - && str_contains($originalValue, $value); - } - - /** - * Test if is possible apply MIME-encoding - * - * @param string $value - * @return bool - */ - public static function canBeEncoded($value) - { - // avoid any wrapping by specifying line length long enough - // "test" -> 4 - // "x-test: =?ISO-8859-1?B?dGVzdA==?=" -> 33 - // 8 +2 +3 +3 -> 16 - $charset = 'UTF-8'; - $lineLength = strlen($value) * 4 + strlen($charset) + 16; - - $preferences = [ - 'scheme' => 'Q', - 'input-charset' => $charset, - 'output-charset' => $charset, - 'line-length' => $lineLength, - ]; - - $encoded = iconv_mime_encode('x-test', $value, $preferences); - - return false !== $encoded; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/IdentificationField.php b/lib/laminas/laminas-mail/src/Header/IdentificationField.php deleted file mode 100644 index 79fd2e428..000000000 --- a/lib/laminas/laminas-mail/src/Header/IdentificationField.php +++ /dev/null @@ -1,138 +0,0 @@ -setIds($messageIds); - - return $header; - } - - /** - * @param string $id - * @return string - */ - private static function trimMessageId($id) - { - return trim($id, "\t\n\r\0\x0B<>"); - } - - /** - * @return string - */ - public function getFieldName() - { - return $this->fieldName; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - return implode(Headers::FOLDING, array_map(static fn($id) => sprintf('<%s>', $id), $this->messageIds)); - } - - /** - * @param string $encoding Ignored; headers of this type MUST always be in - * ASCII. - * @return static This method is a no-op, and implements a fluent interface. - */ - public function setEncoding($encoding) - { - return $this; - } - - /** - * @return string Always returns ASCII - */ - public function getEncoding() - { - return 'ASCII'; - } - - /** - * @return string - */ - public function toString() - { - return sprintf('%s: %s', $this->getFieldName(), $this->getFieldValue()); - } - - /** - * Set the message ids - * - * @param string[] $ids - * @return static This method implements a fluent interface. - */ - public function setIds($ids) - { - foreach ($ids as $id) { - if ( - ! HeaderValue::isValid($id) - || preg_match("/[\r\n]/", $id) - ) { - throw new Exception\InvalidArgumentException('Invalid ID detected'); - } - } - - $this->messageIds = array_map([self::class, "trimMessageId"], $ids); - return $this; - } - - /** - * Retrieve the message ids - * - * @return string[] - */ - public function getIds() - { - return $this->messageIds; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/InReplyTo.php b/lib/laminas/laminas-mail/src/Header/InReplyTo.php deleted file mode 100644 index 2a00bd603..000000000 --- a/lib/laminas/laminas-mail/src/Header/InReplyTo.php +++ /dev/null @@ -1,11 +0,0 @@ -setId($value); - - return $header; - } - - /** - * @return string - */ - public function getFieldName() - { - return 'Message-ID'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - return $this->messageId; - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - // This header must be always in US-ASCII - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - return 'ASCII'; - } - - /** - * @return string - */ - public function toString() - { - return 'Message-ID: ' . $this->getFieldValue(); - } - - /** - * Set the message id - * - * @param string|null $id - * @return MessageId - */ - public function setId($id = null) - { - if ($id === null) { - $id = $this->createMessageId(); - } else { - $id = trim($id, '<>'); - } - - if ( - ! HeaderValue::isValid($id) - || preg_match("/[\r\n]/", $id) - ) { - throw new Exception\InvalidArgumentException('Invalid ID detected'); - } - - $this->messageId = sprintf('<%s>', $id); - return $this; - } - - /** - * Retrieve the message id - * - * @return string - */ - public function getId() - { - return $this->messageId; - } - - /** - * Creates the Message-ID - * - * @return string - */ - public function createMessageId() - { - $time = time(); - - if (isset($_SERVER['REMOTE_ADDR'])) { - $user = $_SERVER['REMOTE_ADDR']; - } else { - $user = getmypid(); - } - - $rand = mt_rand(); - - if (isset($_SERVER["SERVER_NAME"])) { - $hostName = $_SERVER["SERVER_NAME"]; - } else { - $hostName = php_uname('n'); - } - - return sha1($time . $user . $rand) . '@' . $hostName; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/MimeVersion.php b/lib/laminas/laminas-mail/src/Header/MimeVersion.php deleted file mode 100644 index dac333ee9..000000000 --- a/lib/laminas/laminas-mail/src/Header/MimeVersion.php +++ /dev/null @@ -1,103 +0,0 @@ -\d+\.\d+)$/', $value, $matches)) { - $header->setVersion($matches['version']); - } - - return $header; - } - - /** - * @return string - */ - public function getFieldName() - { - return 'MIME-Version'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - return $this->version; - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - // This header must be always in US-ASCII - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - return 'ASCII'; - } - - /** - * @return string - */ - public function toString() - { - return 'MIME-Version: ' . $this->getFieldValue(); - } - - /** - * Set the version string used in this header - * - * @param string $version - * @return MimeVersion - */ - public function setVersion($version) - { - if (! preg_match('/^[1-9]\d*\.\d+$/', $version)) { - throw new Exception\InvalidArgumentException('Invalid MIME-Version value detected'); - } - $this->version = $version; - return $this; - } - - /** - * Retrieve the version string for this header - * - * @return string - */ - public function getVersion() - { - return $this->version; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/MultipleHeadersInterface.php b/lib/laminas/laminas-mail/src/Header/MultipleHeadersInterface.php deleted file mode 100644 index b109e68dd..000000000 --- a/lib/laminas/laminas-mail/src/Header/MultipleHeadersInterface.php +++ /dev/null @@ -1,8 +0,0 @@ -value = $value; - } - - /** - * @return string - */ - public function getFieldName() - { - return 'Received'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - return $this->value; - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - // This header must be always in US-ASCII - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - return 'ASCII'; - } - - /** - * @return string - */ - public function toString() - { - return 'Received: ' . $this->getFieldValue(); - } - - /** - * Serialize collection of Received headers to string - * - * @param array $headers - * @throws Exception\RuntimeException - * @return string - */ - public function toStringMultipleHeaders(array $headers) - { - $strings = [$this->toString()]; - foreach ($headers as $header) { - if (! $header instanceof self) { - throw new Exception\RuntimeException( - 'The Received multiple header implementation can only accept an array of Received headers' - ); - } - $strings[] = $header->toString(); - } - return implode(Headers::EOL, $strings); - } -} diff --git a/lib/laminas/laminas-mail/src/Header/References.php b/lib/laminas/laminas-mail/src/Header/References.php deleted file mode 100644 index f9701408f..000000000 --- a/lib/laminas/laminas-mail/src/Header/References.php +++ /dev/null @@ -1,11 +0,0 @@ - when a name is present - * 'name' and 'email' capture groups correspond respectively to 'display-name' and 'addr-spec' in the ABNF - * - * @see https://tools.ietf.org/html/rfc5322#section-3.4 - */ - $hasMatches = preg_match( - '/^(?:(?P.+)\s)?(?(name)<|[^\s]+?)(?(name)>|>?)$/', - $value, - $matches - ); - - if ($hasMatches !== 1) { - throw new Exception\InvalidArgumentException('Invalid header value for Sender string'); - } - - $senderName = trim($matches['name']); - - if (empty($senderName)) { - $senderName = null; - } - - $header->setAddress($matches['email'], $senderName); - - return $header; - } - - /** - * @return string - */ - public function getFieldName() - { - return 'Sender'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - if (! $this->address instanceof Mail\Address\AddressInterface) { - return ''; - } - - $email = sprintf('<%s>', $this->address->getEmail()); - $name = $this->address->getName(); - - if (! empty($name)) { - if ($format == HeaderInterface::FORMAT_ENCODED) { - $encoding = $this->getEncoding(); - if ('ASCII' !== $encoding) { - $name = HeaderWrap::mimeEncodeValue($name, $encoding); - } - } - $email = sprintf('%s %s', $name, $email); - } - - return $email; - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - $this->encoding = $encoding; - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - if (! $this->encoding) { - $this->encoding = Mime::isPrintable($this->getFieldValue(HeaderInterface::FORMAT_RAW)) - ? 'ASCII' - : 'UTF-8'; - } - - return $this->encoding; - } - - /** - * @return string - */ - public function toString() - { - return 'Sender: ' . $this->getFieldValue(HeaderInterface::FORMAT_ENCODED); - } - - /** - * Set the address used in this header - * - * @param string|AddressInterface $emailOrAddress - * @param null|string $name - * @throws Exception\InvalidArgumentException - * @return Sender - */ - public function setAddress($emailOrAddress, $name = null) - { - if (is_string($emailOrAddress)) { - $emailOrAddress = new Mail\Address($emailOrAddress, $name); - } elseif (! $emailOrAddress instanceof Mail\Address\AddressInterface) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects a string or AddressInterface object; received "%s"', - __METHOD__, - is_object($emailOrAddress) ? $emailOrAddress::class : gettype($emailOrAddress) - )); - } - $this->address = $emailOrAddress; - return $this; - } - - /** - * Retrieve the internal address from this header - * - * @return AddressInterface|null - */ - public function getAddress() - { - return $this->address; - } -} diff --git a/lib/laminas/laminas-mail/src/Header/StructuredInterface.php b/lib/laminas/laminas-mail/src/Header/StructuredInterface.php deleted file mode 100644 index f487bb3f2..000000000 --- a/lib/laminas/laminas-mail/src/Header/StructuredInterface.php +++ /dev/null @@ -1,13 +0,0 @@ -setSubject($value); - - return $header; - } - - /** - * @return string - */ - public function getFieldName() - { - return 'Subject'; - } - - /** - * @inheritDoc - */ - public function getFieldValue($format = HeaderInterface::FORMAT_RAW) - { - if (HeaderInterface::FORMAT_ENCODED === $format) { - return HeaderWrap::wrap($this->subject, $this); - } - - return $this->subject; - } - - /** - * @param string $encoding - * @return self - */ - public function setEncoding($encoding) - { - if ($encoding === $this->encoding) { - return $this; - } - - if ($encoding === null) { - $this->encoding = null; - return $this; - } - - $encoding = strtoupper($encoding); - if ($encoding === 'UTF-8') { - $this->encoding = $encoding; - return $this; - } - - if ($encoding === 'ASCII' && Mime::isPrintable($this->subject)) { - $this->encoding = $encoding; - return $this; - } - - $this->encoding = null; - - return $this; - } - - /** - * @return string - */ - public function getEncoding() - { - if (! $this->encoding) { - $this->encoding = Mime::isPrintable($this->subject) ? 'ASCII' : 'UTF-8'; - } - - return $this->encoding; - } - - /** - * @param string $subject - * @return self - */ - public function setSubject($subject) - { - $subject = (string) $subject; - - if (! HeaderWrap::canBeEncoded($subject)) { - throw new Exception\InvalidArgumentException( - 'Subject value must be composed of printable US-ASCII or UTF-8 characters.' - ); - } - - $this->subject = $subject; - $this->encoding = null; - - return $this; - } - - /** - * @return string - */ - public function toString() - { - return 'Subject: ' . $this->getFieldValue(HeaderInterface::FORMAT_ENCODED); - } -} diff --git a/lib/laminas/laminas-mail/src/Header/To.php b/lib/laminas/laminas-mail/src/Header/To.php deleted file mode 100644 index 42355460c..000000000 --- a/lib/laminas/laminas-mail/src/Header/To.php +++ /dev/null @@ -1,11 +0,0 @@ - - */ -class Headers implements Countable, Iterator -{ - /** @var string End of Line for fields */ - public const EOL = "\r\n"; - - /** @var string Start of Line when folding */ - public const FOLDING = "\r\n "; - - private ?HeaderLocatorInterface $headerLocator = null; - - /** - * @todo Remove for 3.0.0. - * @var null|PluginClassLocator - */ - protected $pluginClassLoader; - - /** @var list key names for $headers array */ - protected $headersKeys = []; - - /** @var list instances */ - protected $headers = []; - - /** - * Header encoding; defaults to ASCII - * - * @var string - */ - protected $encoding = 'ASCII'; - - /** - * Populates headers from string representation - * - * Parses a string for headers, and aggregates them, in order, in the - * current instance, primarily as strings until they are needed (they - * will be lazy loaded) - * - * @param string $string - * @param string $eol EOL string; defaults to {@link EOL} - * @return Headers - * @throws Exception\RuntimeException - */ - public static function fromString($string, $eol = self::EOL) - { - $headers = new static(); - $currentLine = ''; - $emptyLine = 0; - - // iterate the header lines, some might be continuations - $lines = explode($eol, $string); - $total = count($lines); - for ($i = 0; $i < $total; $i += 1) { - $line = $lines[$i]; - - if ($line === "") { - // Empty line indicates end of headers - // EXCEPT if there are more lines, in which case, there's a possible error condition - $emptyLine += 1; - if ($emptyLine > 2) { - throw new Exception\RuntimeException('Malformed header detected'); - } - continue; - } elseif (preg_match('/^\s*$/', $line)) { - // skip empty continuation line - continue; - } - - if ($emptyLine > 1) { - throw new Exception\RuntimeException('Malformed header detected'); - } - - // check if a header name is present - if (preg_match('/^[\x21-\x39\x3B-\x7E]+:.*$/', $line)) { - if ($currentLine) { - // a header name was present, then store the current complete line - $headers->addHeaderLine($currentLine); - } - $currentLine = trim($line); - continue; - } - - // continuation: append to current line - // recover the whitespace that break the line (unfolding, rfc2822#section-2.2.3) - if (preg_match('/^\s+.*$/', $line)) { - $currentLine .= ' ' . trim($line); - continue; - } - - // Line does not match header format! - throw new Exception\RuntimeException(sprintf( - 'Line "%s" does not match header format!', - $line - )); - } - if ($currentLine) { - $headers->addHeaderLine($currentLine); - } - return $headers; - } - - /** - * Set an alternate PluginClassLocator implementation for loading header classes. - * - * @deprecated since 2.12.0 - * - * @todo Remove for version 3.0.0 - * @return $this - */ - public function setPluginClassLoader(PluginClassLocator $pluginClassLoader) - { - // Silenced; can be caught in custom error handlers. - @trigger_error(sprintf( - 'Since laminas/laminas-mail 2.12.0: Usage of %s is deprecated; use %s::setHeaderLocator() instead', - __METHOD__, - self::class - ), E_USER_DEPRECATED); - - $this->pluginClassLoader = $pluginClassLoader; - return $this; - } - - /** - * Return a PluginClassLocator instance for customizing headers. - * - * Lazyloads a Header\HeaderLoader if necessary. - * - * @deprecated since 2.12.0 - * - * @todo Remove for version 3.0.0 - * @return PluginClassLocator - */ - public function getPluginClassLoader() - { - // Silenced; can be caught in custom error handlers. - @trigger_error(sprintf( - 'Since laminas/laminas-mail 2.12.0: Usage of %s is deprecated; use %s::getHeaderLocator() instead', - __METHOD__, - self::class - ), E_USER_DEPRECATED); - - if (! $this->pluginClassLoader) { - $this->pluginClassLoader = new Header\HeaderLoader(); - } - - return $this->pluginClassLoader; - } - - /** - * Retrieve the header class locator for customizing headers. - * - * Lazyloads a Header\HeaderLocator instance if necessary. - */ - public function getHeaderLocator(): HeaderLocatorInterface - { - if (! $this->headerLocator) { - $this->setHeaderLocator(new Header\HeaderLocator()); - } - - assert($this->headerLocator instanceof HeaderLocatorInterface); - - return $this->headerLocator; - } - - /** - * @todo Return self when we update to 7.4 or later as minimum PHP version. - * @return $this - */ - public function setHeaderLocator(HeaderLocatorInterface $headerLocator) - { - $this->headerLocator = $headerLocator; - return $this; - } - - /** - * Set the header encoding - * - * @param string $encoding - * @return Headers - */ - public function setEncoding($encoding) - { - $this->encoding = $encoding; - foreach ($this as $header) { - $header->setEncoding($encoding); - } - return $this; - } - - /** - * Get the header encoding - * - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Add many headers at once - * - * Expects an array (or Traversable object) of type/value pairs. - * - * @param array|Traversable $headers - * @throws Exception\InvalidArgumentException - * @return Headers - */ - public function addHeaders($headers) - { - if (! is_array($headers) && ! $headers instanceof Traversable) { - throw new Exception\InvalidArgumentException(sprintf( - 'Expected array or Traversable; received "%s"', - is_object($headers) ? $headers::class : gettype($headers) - )); - } - - foreach ($headers as $name => $value) { - if (is_int($name)) { - if (is_string($value)) { - $this->addHeaderLine($value); - } elseif (is_array($value) && count($value) == 1) { - $this->addHeaderLine(key($value), current($value)); - } elseif (is_array($value) && count($value) == 2) { - $this->addHeaderLine($value[0], $value[1]); - } elseif ($value instanceof Header\HeaderInterface) { - $this->addHeader($value); - } - } elseif (is_string($name)) { - $this->addHeaderLine($name, $value); - } - } - - return $this; - } - - /** - * Add a raw header line, either in name => value, or as a single string 'name: value' - * - * This method allows for lazy-loading in that the parsing and instantiation of HeaderInterface object - * will be delayed until they are retrieved by either get() or current() - * - * @throws Exception\InvalidArgumentException - * @param string $headerFieldNameOrLine - * @param string $fieldValue optional - * @return Headers - */ - public function addHeaderLine($headerFieldNameOrLine, $fieldValue = null) - { - if (! is_string($headerFieldNameOrLine)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects its first argument to be a string; received "%s"', - __METHOD__, - is_object($headerFieldNameOrLine) - ? $headerFieldNameOrLine::class - : gettype($headerFieldNameOrLine) - )); - } - - if ($fieldValue === null) { - $headers = $this->loadHeader($headerFieldNameOrLine); - $headers = is_array($headers) ? $headers : [$headers]; - foreach ($headers as $header) { - $this->addHeader($header); - } - } elseif (is_array($fieldValue)) { - foreach ($fieldValue as $i) { - $this->addHeader(Header\GenericMultiHeader::fromString($headerFieldNameOrLine . ':' . $i)); - } - } else { - $this->addHeader(GenericHeader::fromString($headerFieldNameOrLine . ':' . $fieldValue)); - } - - return $this; - } - - /** - * Add a Header\Interface to this container, for raw values see {@link addHeaderLine()} and {@link addHeaders()} - * - * @return Headers - */ - public function addHeader(HeaderInterface $header) - { - $key = $this->normalizeFieldName($header->getFieldName()); - $this->headersKeys[] = $key; - $this->headers[] = $header; - if ($this->getEncoding() !== 'ASCII') { - $header->setEncoding($this->getEncoding()); - } - return $this; - } - - /** - * Remove a Header from the container - * - * @param string|HeaderInterface $instanceOrFieldName field name or specific header instance to remove - * @return bool - */ - public function removeHeader($instanceOrFieldName) - { - if (! $instanceOrFieldName instanceof Header\HeaderInterface && ! is_string($instanceOrFieldName)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s requires a string or %s instance; received %s', - __METHOD__, - HeaderInterface::class, - is_object($instanceOrFieldName) ? $instanceOrFieldName::class : gettype($instanceOrFieldName) - )); - } - - if ($instanceOrFieldName instanceof Header\HeaderInterface) { - $indexes = array_keys($this->headers, $instanceOrFieldName, true); - } - - if (is_string($instanceOrFieldName)) { - $key = $this->normalizeFieldName($instanceOrFieldName); - $indexes = array_keys($this->headersKeys, $key, true); - } - - if (! empty($indexes)) { - foreach ($indexes as $index) { - unset($this->headersKeys[$index]); - unset($this->headers[$index]); - } - return true; - } - - return false; - } - - /** - * Clear all headers - * - * Removes all headers from queue - * - * @return Headers - */ - public function clearHeaders() - { - $this->headers = $this->headersKeys = []; - return $this; - } - - /** - * Get all headers of a certain name/type - * - * @param string $name - * @return false|ArrayIterator|HeaderInterface Returns false if there is no headers with $name in this - * contain, an ArrayIterator if the header is a MultipleHeadersInterface instance and finally returns - * HeaderInterface for the rest of cases. - */ - public function get($name) - { - $key = $this->normalizeFieldName($name); - $results = []; - - foreach (array_keys($this->headersKeys, $key, true) as $index) { - if ($this->headers[$index] instanceof Header\GenericHeader) { - $results[] = $this->lazyLoadHeader($index); - } else { - $results[] = $this->headers[$index]; - } - } - - switch (count($results)) { - case 0: - return false; - case 1: - if ($results[0] instanceof Header\MultipleHeadersInterface) { - return new ArrayIterator($results); - } - return $results[0]; - default: - return new ArrayIterator($results); - } - } - - /** - * Test for existence of a type of header - * - * @param string $name - * @return bool - */ - public function has($name) - { - $name = $this->normalizeFieldName($name); - return in_array($name, $this->headersKeys, true); - } - - /** - * Advance the pointer for this object as an iterator - */ - #[ReturnTypeWillChange] - public function next() - { - next($this->headers); - } - - /** - * Return the current key for this object as an iterator - * - * @return mixed - */ - #[ReturnTypeWillChange] - public function key() - { - return key($this->headers); - } - - /** - * Is this iterator still valid? - * - * @return bool - */ - #[ReturnTypeWillChange] - public function valid() - { - return current($this->headers) !== false; - } - - /** - * Reset the internal pointer for this object as an iterator - */ - #[ReturnTypeWillChange] - public function rewind() - { - reset($this->headers); - } - - /** - * Return the current value for this iterator, lazy loading it if need be - * - * @return HeaderInterface - */ - #[ReturnTypeWillChange] - public function current() - { - $current = current($this->headers); - if ($current instanceof Header\GenericHeader) { - $current = $this->lazyLoadHeader(key($this->headers)); - } - return $current; - } - - /** - * Return the number of headers in this contain, if all headers have not been parsed, actual count could - * increase if MultipleHeader objects exist in the Request/Response. If you need an exact count, iterate - * - * @return int count of currently known headers - */ - #[ReturnTypeWillChange] - public function count() - { - return count($this->headers); - } - - /** - * Render all headers at once - * - * This method handles the normal iteration of headers; it is up to the - * concrete classes to prepend with the appropriate status/request line. - * - * @return string - */ - public function toString() - { - $headers = ''; - foreach ($this as $header) { - if ($str = $header->toString()) { - $headers .= $str . self::EOL; - } - } - - return $headers; - } - - /** - * Return the headers container as an array - * - * @param bool $format Return the values in Mime::Encoded or in Raw format - * @return array|string> - * @todo determine how to produce single line headers, if they are supported - */ - public function toArray($format = HeaderInterface::FORMAT_RAW) - { - $headers = []; - foreach ($this->headers as $header) { - if ($header instanceof Header\MultipleHeadersInterface) { - $name = $header->getFieldName(); - if (! isset($headers[$name])) { - $headers[$name] = []; - } - $headers[$name][] = $header->getFieldValue($format); - } else { - $headers[$header->getFieldName()] = $header->getFieldValue($format); - } - } - return $headers; - } - - /** - * By calling this, it will force parsing and loading of all headers, after this count() will be accurate - * - * @return bool - */ - public function forceLoading() - { - // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach - foreach ($this as $item) { - // $item should now be loaded - } - return true; - } - - /** - * Create Header object from header line - * - * @param string $headerLine - * @return HeaderInterface|HeaderInterface[] - */ - public function loadHeader($headerLine) - { - [$name] = GenericHeader::splitHeaderLine($headerLine); - - /** @var HeaderInterface $class */ - $class = $this->resolveHeaderClass($name); - return $class::fromString($headerLine); - } - - /** - * @param array-key $index - * @return mixed - */ - protected function lazyLoadHeader($index) - { - $current = $this->headers[$index]; - - $key = $this->headersKeys[$index]; - - /** @var GenericHeader $class */ - $class = $this->resolveHeaderClass($key); - - $encoding = $current->getEncoding(); - $headers = $class::fromString($current->toString()); - if (is_array($headers)) { - $current = array_shift($headers); - $current->setEncoding($encoding); - $this->headers[$index] = $current; - foreach ($headers as $header) { - $header->setEncoding($encoding); - $this->headersKeys[] = $key; - $this->headers[] = $header; - } - return $current; - } - - $current = $headers; - $current->setEncoding($encoding); - $this->headers[$index] = $current; - return $current; - } - - /** - * Normalize a field name - * - * @param string $fieldName - * @return string - */ - protected function normalizeFieldName($fieldName) - { - return str_replace(['-', '_', ' ', '.'], '', strtolower($fieldName)); - } - - /** - * @param string $key - * @return null|string - */ - private function resolveHeaderClass($key) - { - if ($this->pluginClassLoader) { - return $this->pluginClassLoader->load($key) ?: GenericHeader::class; - } - return $this->getHeaderLocator()->get($key, GenericHeader::class); - } -} diff --git a/lib/laminas/laminas-mail/src/Message.php b/lib/laminas/laminas-mail/src/Message.php deleted file mode 100644 index f0e748407..000000000 --- a/lib/laminas/laminas-mail/src/Message.php +++ /dev/null @@ -1,581 +0,0 @@ -getFrom(); - if (! $from instanceof AddressList) { - return false; - } - return (bool) count($from); - } - - /** - * Set the message encoding - * - * @param string $encoding - * @return Message - */ - public function setEncoding($encoding) - { - $this->encoding = $encoding; - $this->getHeaders()->setEncoding($encoding); - return $this; - } - - /** - * Get the message encoding - * - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Compose headers - * - * @return Message - */ - public function setHeaders(Headers $headers) - { - $this->headers = $headers; - $headers->setEncoding($this->getEncoding()); - return $this; - } - - /** - * Access headers collection - * - * Lazy-loads if not already attached. - * - * @return Headers - */ - public function getHeaders() - { - if (null === $this->headers) { - $this->setHeaders(new Headers()); - $date = Header\Date::fromString('Date: ' . date('r')); - $this->headers->addHeader($date); - } - return $this->headers; - } - - /** - * Set (overwrite) From addresses - * - * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList - * @param string|null $name - * @return Message - */ - public function setFrom($emailOrAddressList, $name = null) - { - $this->clearHeaderByName('from'); - return $this->addFrom($emailOrAddressList, $name); - } - - /** - * Add a "From" address - * - * @param string|Address|array|AddressList|Traversable $emailOrAddressOrList - * @param string|null $name - * @return Message - */ - public function addFrom($emailOrAddressOrList, $name = null) - { - $addressList = $this->getFrom(); - $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__); - return $this; - } - - /** - * Retrieve list of From senders - * - * @return AddressList - */ - public function getFrom() - { - return $this->getAddressListFromHeader('from', From::class); - } - - /** - * Overwrite the address list in the To recipients - * - * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList - * @param null|string $name - * @return Message - */ - public function setTo($emailOrAddressList, $name = null) - { - $this->clearHeaderByName('to'); - return $this->addTo($emailOrAddressList, $name); - } - - /** - * Add one or more addresses to the To recipients - * - * Appends to the list. - * - * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressOrList - * @param null|string $name - * @return Message - */ - public function addTo($emailOrAddressOrList, $name = null) - { - $addressList = $this->getTo(); - $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__); - return $this; - } - - /** - * Access the address list of the To header - * - * @return AddressList - */ - public function getTo() - { - return $this->getAddressListFromHeader('to', To::class); - } - - /** - * Set (overwrite) CC addresses - * - * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList - * @param string|null $name - * @return Message - */ - public function setCc($emailOrAddressList, $name = null) - { - $this->clearHeaderByName('cc'); - return $this->addCc($emailOrAddressList, $name); - } - - /** - * Add a "Cc" address - * - * @param string|Address|array|AddressList|Traversable $emailOrAddressOrList - * @param string|null $name - * @return Message - */ - public function addCc($emailOrAddressOrList, $name = null) - { - $addressList = $this->getCc(); - $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__); - return $this; - } - - /** - * Retrieve list of CC recipients - * - * @return AddressList - */ - public function getCc() - { - return $this->getAddressListFromHeader('cc', Cc::class); - } - - /** - * Set (overwrite) BCC addresses - * - * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList - * @param string|null $name - * @return Message - */ - public function setBcc($emailOrAddressList, $name = null) - { - $this->clearHeaderByName('bcc'); - return $this->addBcc($emailOrAddressList, $name); - } - - /** - * Add a "Bcc" address - * - * @param string|Address|array|AddressList|Traversable $emailOrAddressOrList - * @param string|null $name - * @return Message - */ - public function addBcc($emailOrAddressOrList, $name = null) - { - $addressList = $this->getBcc(); - $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__); - return $this; - } - - /** - * Retrieve list of BCC recipients - * - * @return AddressList - */ - public function getBcc() - { - return $this->getAddressListFromHeader('bcc', Bcc::class); - } - - /** - * Overwrite the address list in the Reply-To recipients - * - * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressList - * @param null|string $name - * @return Message - */ - public function setReplyTo($emailOrAddressList, $name = null) - { - $this->clearHeaderByName('reply-to'); - return $this->addReplyTo($emailOrAddressList, $name); - } - - /** - * Add one or more addresses to the Reply-To recipients - * - * Appends to the list. - * - * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressOrList - * @param null|string $name - * @return Message - */ - public function addReplyTo($emailOrAddressOrList, $name = null) - { - $addressList = $this->getReplyTo(); - $this->updateAddressList($addressList, $emailOrAddressOrList, $name, __METHOD__); - return $this; - } - - /** - * Access the address list of the Reply-To header - * - * @return AddressList - */ - public function getReplyTo() - { - return $this->getAddressListFromHeader('reply-to', ReplyTo::class); - } - - /** - * setSender - * - * @return Message - */ - public function setSender(mixed $emailOrAddress, mixed $name = null) - { - /** @var Sender $header */ - $header = $this->getHeaderByName('sender', Sender::class); - $header->setAddress($emailOrAddress, $name); - return $this; - } - - /** - * Retrieve the sender address, if any - * - * @return null|Address\AddressInterface - */ - public function getSender() - { - $headers = $this->getHeaders(); - if (! $headers->has('sender')) { - return null; - } - - /** @var Sender $header */ - $header = $this->getHeaderByName('sender', Sender::class); - return $header->getAddress(); - } - - /** - * Set the message subject header value - * - * @param string $subject - * @return Message - */ - public function setSubject($subject) - { - $headers = $this->getHeaders(); - if (! $headers->has('subject')) { - $header = new Header\Subject(); - $headers->addHeader($header); - } else { - $header = $headers->get('subject'); - } - $header->setSubject($subject); - $header->setEncoding($this->getEncoding()); - return $this; - } - - /** - * Get the message subject header value - * - * @return null|string - */ - public function getSubject() - { - $headers = $this->getHeaders(); - if (! $headers->has('subject')) { - return; - } - $header = $headers->get('subject'); - return $header->getFieldValue(); - } - - /** - * Set the message body - * - * @param null|string|\Laminas\Mime\Message|object $body - * @throws Exception\InvalidArgumentException - * @return Message - */ - public function setBody($body) - { - if (! is_string($body) && $body !== null) { - if (! is_object($body)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects a string or object argument; received "%s"', - __METHOD__, - gettype($body) - )); - } - if (! $body instanceof Mime\Message) { - if (! method_exists($body, '__toString')) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects object arguments of type %s or implementing __toString();' - . ' object of type "%s" received', - __METHOD__, - Mime\Message::class, - $body::class - )); - } - } - } - $this->body = $body; - - if (! $this->body instanceof Mime\Message) { - return $this; - } - - // Get headers, and set Mime-Version header - $headers = $this->getHeaders(); - $this->getHeaderByName('mime-version', MimeVersion::class); - - // Multipart content headers - if ($this->body->isMultiPart()) { - $mime = $this->body->getMime(); - - /** @var ContentType $header */ - $header = $this->getHeaderByName('content-type', ContentType::class); - $header->setType('multipart/mixed'); - $header->addParameter('boundary', $mime->boundary()); - return $this; - } - - // MIME single part headers - $parts = $this->body->getParts(); - if (! empty($parts)) { - $part = array_shift($parts); - $headers->addHeaders($part->getHeadersArray("\r\n")); - } - return $this; - } - - /** - * Return the currently set message body - * - * @return object|string|Mime\Message - */ - public function getBody() - { - return $this->body; - } - - /** - * Get the string-serialized message body text - * - * @return string - */ - public function getBodyText() - { - if ($this->body instanceof Mime\Message) { - return $this->body->generateMessage(Headers::EOL); - } - - return (string) $this->body; - } - - /** - * Retrieve a header by name - * - * If not found, instantiates one based on $headerClass. - * - * @param string $headerName - * @param string $headerClass - * @return Header\HeaderInterface|ArrayIterator header instance or collection of headers - */ - protected function getHeaderByName($headerName, $headerClass) - { - $headers = $this->getHeaders(); - if ($headers->has($headerName)) { - $header = $headers->get($headerName); - } else { - $header = new $headerClass(); - $headers->addHeader($header); - } - return $header; - } - - /** - * Clear a header by name - * - * @param string $headerName - */ - protected function clearHeaderByName($headerName) - { - $this->getHeaders()->removeHeader($headerName); - } - - /** - * Retrieve the AddressList from a named header - * - * Used with To, From, Cc, Bcc, and ReplyTo headers. If the header does not - * exist, instantiates it. - * - * @param string $headerName - * @param string $headerClass - * @throws Exception\DomainException - * @return AddressList - */ - protected function getAddressListFromHeader($headerName, $headerClass) - { - $header = $this->getHeaderByName($headerName, $headerClass); - if (! $header instanceof Header\AbstractAddressList) { - throw new Exception\DomainException(sprintf( - 'Cannot grab address list from header of type "%s"; not an AbstractAddressList implementation', - $header::class - )); - } - return $header->getAddressList(); - } - - /** - * Update an address list - * - * Proxied to this from addFrom, addTo, addCc, addBcc, and addReplyTo. - * - * @param string|Address\AddressInterface|array|AddressList|Traversable $emailOrAddressOrList - * @param null|string $name - * @param string $callingMethod - * @throws Exception\InvalidArgumentException - */ - protected function updateAddressList(AddressList $addressList, $emailOrAddressOrList, $name, $callingMethod) - { - if ($emailOrAddressOrList instanceof Traversable) { - foreach ($emailOrAddressOrList as $address) { - $addressList->add($address); - } - return; - } - if (is_array($emailOrAddressOrList)) { - $addressList->addMany($emailOrAddressOrList); - return; - } - if (! is_string($emailOrAddressOrList) && ! $emailOrAddressOrList instanceof Address\AddressInterface) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects a string, AddressInterface, array, AddressList, or Traversable as its first argument;' - . ' received "%s"', - $callingMethod, - is_object($emailOrAddressOrList) ? $emailOrAddressOrList::class : gettype($emailOrAddressOrList) - )); - } - - if (is_string($emailOrAddressOrList) && $name === null) { - $addressList->addFromString($emailOrAddressOrList); - return; - } - - $addressList->add($emailOrAddressOrList, $name); - } - - /** - * Serialize to string - * - * @return string - */ - public function toString() - { - $headers = $this->getHeaders(); - return $headers->toString() - . Headers::EOL - . $this->getBodyText(); - } - - /** - * Instantiate from raw message string - * - * @todo Restore body to Mime\Message - * @param string $rawMessage - * @return Message - */ - public static function fromString($rawMessage) - { - $message = new static(); - - /** @var Headers $headers */ - $headers = null; - $content = null; - Mime\Decode::splitMessage($rawMessage, $headers, $content, Headers::EOL); - // if ($headers->has('mime-version')) { - // todo - restore body to mime\message - // } - $message->setHeaders($headers); - $message->setBody($content); - return $message; - } -} diff --git a/lib/laminas/laminas-mail/src/MessageFactory.php b/lib/laminas/laminas-mail/src/MessageFactory.php deleted file mode 100644 index e5ebcda11..000000000 --- a/lib/laminas/laminas-mail/src/MessageFactory.php +++ /dev/null @@ -1,67 +0,0 @@ - $value) { - $setter = self::getSetterMethod($key); - if (method_exists($message, $setter)) { - $message->{$setter}($value); - } - } - - return $message; - } - - /** - * Generate a setter method name based on a provided key. - * - * @param string $key - * @return string - */ - private static function getSetterMethod($key) - { - return 'set' - . str_replace( - ' ', - '', - ucwords( - strtr( - $key, - [ - '-' => ' ', - '_' => ' ', - ] - ) - ) - ); - } -} diff --git a/lib/laminas/laminas-mail/src/Module.php b/lib/laminas/laminas-mail/src/Module.php deleted file mode 100644 index 652dfcb7c..000000000 --- a/lib/laminas/laminas-mail/src/Module.php +++ /dev/null @@ -1,19 +0,0 @@ - $provider->getDependencyConfig(), - ]; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/AbstractProtocol.php b/lib/laminas/laminas-mail/src/Protocol/AbstractProtocol.php deleted file mode 100644 index 9dfe67c33..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/AbstractProtocol.php +++ /dev/null @@ -1,360 +0,0 @@ -validHost = new Validator\ValidatorChain(); - $this->validHost->attach(new Validator\Hostname(Validator\Hostname::ALLOW_ALL)); - - if (! $this->validHost->isValid($host)) { - throw new Exception\RuntimeException(implode(', ', $this->validHost->getMessages())); - } - - $this->host = $host; - } - - /** - * Class destructor to cleanup open resources - */ - public function __destruct() - { - $this->_disconnect(); - } - - /** - * Set the maximum log size - * - * @param int $maximumLog Maximum log size - */ - public function setMaximumLog($maximumLog) - { - $this->maximumLog = (int) $maximumLog; - } - - /** - * Get the maximum log size - * - * @return int the maximum log size - */ - public function getMaximumLog() - { - return $this->maximumLog; - } - - /** - * Create a connection to the remote host - * - * Concrete adapters for this class will implement their own unique connect - * scripts, using the _connect() method to create the socket resource. - */ - abstract public function connect(); - - /** - * Retrieve the last client request - * - * @return string - */ - public function getRequest() - { - return $this->request; - } - - /** - * Retrieve the last server response - * - * @return array - */ - public function getResponse() - { - return $this->response; - } - - /** - * Retrieve the transaction log - * - * @return string - */ - public function getLog() - { - return implode('', $this->log); - } - - /** - * Reset the transaction log - */ - public function resetLog() - { - $this->log = []; - } - - /** - * Add the transaction log - * - * @param string $value new transaction - */ - // @codingStandardsIgnoreLine PSR2.Methods.MethodDeclaration.Underscore - protected function _addLog($value) - { - if ($this->maximumLog >= 0 && count($this->log) >= $this->maximumLog) { - array_shift($this->log); - } - - $this->log[] = $value; - } - - /** - * Connect to the server using the supplied transport and target - * - * An example $remote string may be 'tcp://mail.example.com:25' or 'ssh://hostname.com:2222' - * - * @deprecated Since 1.12.0. Implementations should use the ProtocolTrait::setupSocket() method instead. - * - * @todo Remove for 3.0.0. - * @param string $remote Remote - * @throws Exception\RuntimeException - * @return bool - */ - // @codingStandardsIgnoreLine PSR2.Methods.MethodDeclaration.Underscore - protected function _connect($remote) - { - $errorNum = 0; - $errorStr = ''; - - // open connection - set_error_handler( - static function ($error, $message = '') { - throw new Exception\RuntimeException(sprintf('Could not open socket: %s', $message), $error); - }, - E_WARNING - ); - $this->socket = stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION); - restore_error_handler(); - - if ($this->socket === false) { - if ($errorNum == 0) { - $errorStr = 'Could not open socket'; - } - throw new Exception\RuntimeException($errorStr); - } - - if (($result = stream_set_timeout($this->socket, self::TIMEOUT_CONNECTION)) === false) { - throw new Exception\RuntimeException('Could not set stream timeout'); - } - - return $result; - } - - /** - * Disconnect from remote host and free resource - */ - // @codingStandardsIgnoreLine PSR2.Methods.MethodDeclaration.Underscore - protected function _disconnect() - { - if (is_resource($this->socket)) { - fclose($this->socket); - } - } - - /** - * Send the given request followed by a LINEEND to the server. - * - * @param string $request - * @throws Exception\RuntimeException - * @return int|bool Number of bytes written to remote host - */ - // @codingStandardsIgnoreLine PSR2.Methods.MethodDeclaration.Underscore - protected function _send($request) - { - if (! is_resource($this->socket)) { - throw new Exception\RuntimeException('No connection has been established to ' . $this->host); - } - - $this->request = $request; - - $result = fwrite($this->socket, $request . self::EOL); - - // Save request to internal log - $this->_addLog($request . self::EOL); - - if ($result === false) { - throw new Exception\RuntimeException('Could not send request to ' . $this->host); - } - - return $result; - } - - /** - * Get a line from the stream. - * - * @param int $timeout Per-request timeout value if applicable - * @throws Exception\RuntimeException - * @return string - */ - // @codingStandardsIgnoreLine PSR2.Methods.MethodDeclaration.Underscore - protected function _receive($timeout = null) - { - if (! is_resource($this->socket)) { - throw new Exception\RuntimeException('No connection has been established to ' . $this->host); - } - - // Adapters may wish to supply per-commend timeouts according to appropriate RFC - if ($timeout !== null) { - stream_set_timeout($this->socket, $timeout); - } - - // Retrieve response - $response = fgets($this->socket, 1024); - - // Save request to internal log - $this->_addLog($response); - - // Check meta data to ensure connection is still valid - $info = stream_get_meta_data($this->socket); - - if ($info['timed_out']) { - throw new Exception\RuntimeException($this->host . ' has timed out'); - } - - if ($response === false) { - throw new Exception\RuntimeException('Could not read from ' . $this->host); - } - - return $response; - } - - /** - * Parse server response for successful codes - * - * Read the response from the stream and check for expected return code. - * Throws a Laminas\Mail\Protocol\Exception\ExceptionInterface if an unexpected code is returned. - * - * @param string|array $code One or more codes that indicate a successful response - * @param int $timeout Per-request timeout value if applicable - * @throws Exception\RuntimeException - * @return string Last line of response string - */ - // @codingStandardsIgnoreLine PSR2.Methods.MethodDeclaration.Underscore - protected function _expect($code, $timeout = null) - { - $this->response = []; - $errMsg = ''; - - if (! is_array($code)) { - $code = [$code]; - } - - do { - $this->response[] = $result = $this->_receive($timeout); - [$cmd, $more, $msg] = preg_split('/([\s-]+)/', $result, 2, PREG_SPLIT_DELIM_CAPTURE); - - if ($errMsg !== '') { - $errMsg .= ' ' . $msg; - } elseif ($cmd === null || ! in_array($cmd, $code)) { - $errMsg = $msg; - } - - // The '-' message prefix indicates an information string instead of a response string. - } while (str_starts_with($more, '-')); - - if ($errMsg !== '') { - throw new Exception\RuntimeException($errMsg); - } - - return $msg; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Exception/ExceptionInterface.php b/lib/laminas/laminas-mail/src/Protocol/Exception/ExceptionInterface.php deleted file mode 100644 index 05bfeee21..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Exception/ExceptionInterface.php +++ /dev/null @@ -1,9 +0,0 @@ -setNoValidateCert($novalidatecert); - - if ($host) { - $this->connect($host, $port, $ssl); - } - } - - /** - * Public destructor - */ - public function __destruct() - { - $this->logout(); - } - - /** - * Open connection to IMAP server - * - * @param string $host hostname or IP address of IMAP server - * @param int|null $port of IMAP server, default is 143 (993 for ssl) - * @param string|bool $ssl use 'SSL', 'TLS' or false - * @throws Exception\RuntimeException - * @return void - */ - public function connect($host, $port = null, $ssl = false) - { - $transport = 'tcp'; - $isTls = false; - - if ($ssl) { - $ssl = strtolower($ssl); - } - - switch ($ssl) { - case 'ssl': - $transport = 'ssl'; - if (! $port) { - $port = 993; - } - break; - case 'tls': - $isTls = true; - // break intentionally omitted - default: - if (! $port) { - $port = 143; - } - } - - $this->socket = $this->setupSocket($transport, $host, $port, self::TIMEOUT_CONNECTION); - - if (! $this->assumedNextLine('* OK')) { - throw new Exception\RuntimeException('host doesn\'t allow connection'); - } - - if ($isTls) { - $result = $this->requestAndResponse('STARTTLS'); - $result = $result && stream_socket_enable_crypto($this->socket, true, $this->getCryptoMethod()); - if (! $result) { - throw new Exception\RuntimeException('cannot enable TLS'); - } - } - } - - /** - * get the next line from socket with error checking, but nothing else - * - * @throws Exception\RuntimeException - * @return string next line - */ - protected function nextLine() - { - $line = fgets($this->socket); - if ($line === false) { - throw new Exception\RuntimeException('cannot read - connection closed?'); - } - - return $line; - } - - /** - * get next line and assume it starts with $start. some requests give a simple - * feedback so we can quickly check if we can go on. - * - * @param string $start the first bytes we assume to be in the next line - * @return bool line starts with $start - */ - protected function assumedNextLine($start) - { - $line = $this->nextLine(); - return str_starts_with($line, $start); - } - - /** - * get next line and split the tag. that's the normal case for a response line - * - * @param string $tag tag of line is returned by reference - * @return string next line - */ - protected function nextTaggedLine(&$tag) - { - $line = $this->nextLine(); - - // separate tag from line - [$tag, $line] = explode(' ', $line, 2); - - return $line; - } - - /** - * split a given line in tokens. a token is literal of any form or a list - * - * @param string $line line to decode - * @return array tokens, literals are returned as string, lists as array - */ - protected function decodeLine($line) - { - $tokens = []; - $stack = []; - - /* - We start to decode the response here. The understood tokens are: - literal - "literal" or also "lit\\er\"al" - {bytes}literal - (literals*) - All tokens are returned in an array. Literals in braces (the last understood - token in the list) are returned as an array of tokens. I.e. the following response: - "foo" baz {3}bar ("f\\\"oo" bar) - would be returned as: - array('foo', 'baz', 'bar', array('f\\\"oo', 'bar')); - - // TODO: add handling of '[' and ']' to parser for easier handling of response text - */ - // replace any trailing including spaces with a single space - $line = rtrim($line) . ' '; - while (($pos = strpos($line, ' ')) !== false) { - $token = substr($line, 0, $pos); - if (! strlen($token)) { - continue; - } - while ($token[0] == '(') { - array_push($stack, $tokens); - $tokens = []; - $token = substr($token, 1); - } - if ($token[0] == '"') { - if (preg_match('%^\(*"((.|\\\\|\\")*?)" *%', $line, $matches)) { - $tokens[] = $matches[1]; - $line = substr($line, strlen($matches[0])); - continue; - } - } - if ($token[0] == '{') { - $endPos = strpos($token, '}'); - $chars = substr($token, 1, $endPos - 1); - if (is_numeric($chars)) { - $token = ''; - while (strlen($token) < $chars) { - $token .= $this->nextLine(); - } - $line = ''; - if (strlen($token) > $chars) { - $line = substr($token, $chars); - $token = substr($token, 0, $chars); - } else { - $line .= $this->nextLine(); - } - $tokens[] = $token; - $line = trim($line) . ' '; - continue; - } - } - if ($stack && $token[strlen($token) - 1] == ')') { - // closing braces are not separated by spaces, so we need to count them - $braces = strlen($token); - $token = rtrim($token, ')'); - // only count braces if more than one - $braces -= strlen($token) + 1; - // only add if token had more than just closing braces - if (rtrim($token) != '') { - $tokens[] = rtrim($token); - } - $token = $tokens; - $tokens = array_pop($stack); - // special handline if more than one closing brace - while ($braces-- > 0) { - $tokens[] = $token; - $token = $tokens; - $tokens = array_pop($stack); - } - } - $tokens[] = $token; - $line = substr($line, $pos + 1); - } - - // maybe the server forgot to send some closing braces - while ($stack) { - $child = $tokens; - $tokens = array_pop($stack); - $tokens[] = $child; - } - - return $tokens; - } - - /** - * read a response "line" (could also be more than one real line if response has {..}) - * and do a simple decode - * - * @param array|string $tokens decoded tokens are returned by reference, if $dontParse - * is true the unparsed line is returned here - * @param string $wantedTag check for this tag for response code. Default '*' is - * continuation tag. - * @param bool $dontParse if true only the unparsed line is returned $tokens - * @return bool if returned tag matches wanted tag - */ - public function readLine(&$tokens = [], $wantedTag = '*', $dontParse = false) - { - $tag = null; // define $tag variable before first use - $line = $this->nextTaggedLine($tag); // get next tag - if (! $dontParse) { - $tokens = $this->decodeLine($line); - } else { - $tokens = $line; - } - - // if tag is wanted tag we might be at the end of a multiline response - return $tag == $wantedTag; - } - - /** - * read all lines of response until given tag is found (last line of response) - * - * @param string $tag the tag of your request - * @param bool $dontParse if true every line is returned unparsed instead of - * the decoded tokens - * @return null|bool|array tokens if success, false if error, null if bad request - */ - public function readResponse($tag, $dontParse = false) - { - $lines = []; - $tokens = null; // define $tokens variable before first use - while (! $this->readLine($tokens, $tag, $dontParse)) { - $lines[] = $tokens; - } - - if ($dontParse) { - // last to chars are still needed for response code - $tokens = [substr($tokens, 0, 2)]; - } - - // last line has response code - if ($tokens[0] == 'OK') { - return $lines ?: true; - } elseif ($tokens[0] == 'NO') { - return false; - } - } - - /** - * send a request - * - * @param string $command your request command - * @param array $tokens additional parameters to command, use escapeString() to prepare - * @param string $tag provide a tag otherwise an autogenerated is returned - * @throws Exception\RuntimeException - */ - public function sendRequest($command, $tokens = [], &$tag = null) - { - if (! $tag) { - ++$this->tagCount; - $tag = 'TAG' . $this->tagCount; - } - - $line = $tag . ' ' . $command; - - foreach ($tokens as $token) { - if (is_array($token)) { - if (fwrite($this->socket, $line . ' ' . $token[0] . "\r\n") === false) { - throw new Exception\RuntimeException('cannot write - connection closed?'); - } - if (! $this->assumedNextLine('+ ')) { - throw new Exception\RuntimeException('cannot send literal string'); - } - $line = $token[1]; - } else { - $line .= ' ' . $token; - } - } - - if (fwrite($this->socket, $line . "\r\n") === false) { - throw new Exception\RuntimeException('cannot write - connection closed?'); - } - } - - /** - * send a request and get response at once - * - * @param string $command command as in sendRequest() - * @param array $tokens parameters as in sendRequest() - * @param bool $dontParse if true unparsed lines are returned instead of tokens - * @return mixed response as in readResponse() - */ - public function requestAndResponse($command, $tokens = [], $dontParse = false) - { - $tag = null; // define $tag variable before first use - $this->sendRequest($command, $tokens, $tag); - return $this->readResponse($tag, $dontParse); - } - - /** - * escape one or more literals i.e. for sendRequest - * - * @param string|array $string the literal/-s - * @return string|array escape literals, literals with newline ar returned - * as array('{size}', 'string'); - */ - public function escapeString($string) - { - if (func_num_args() < 2) { - if (str_contains($string, "\n")) { - return ['{' . strlen($string) . '}', $string]; - } - - return '"' . str_replace(['\\', '"'], ['\\\\', '\\"'], $string) . '"'; - } - - $result = []; - foreach (func_get_args() as $string) { - $result[] = $this->escapeString($string); - } - return $result; - } - - /** - * escape a list with literals or lists - * - * @param array $list list with literals or lists as PHP array - * @return string escaped list for imap - */ - public function escapeList($list) - { - $result = []; - foreach ($list as $v) { - if (! is_array($v)) { - $result[] = $v; - continue; - } - $result[] = $this->escapeList($v); - } - return '(' . implode(' ', $result) . ')'; - } - - /** - * Login to IMAP server. - * - * @param string $user username - * @param string $password password - * @return bool success - */ - public function login($user, $password) - { - return $this->requestAndResponse('LOGIN', $this->escapeString($user, $password), true); - } - - /** - * logout of imap server - * - * @return bool success - */ - public function logout() - { - $result = false; - if ($this->socket) { - try { - $result = $this->requestAndResponse('LOGOUT', [], true); - } catch (Exception\ExceptionInterface) { - // ignoring exception - } - fclose($this->socket); - $this->socket = null; - } - return $result; - } - - /** - * Get capabilities from IMAP server - * - * @return array list of capabilities - * @throws ExceptionInterface - */ - public function capability() - { - $response = $this->requestAndResponse('CAPABILITY'); - - if (! $response) { - return []; - } - - $capabilities = []; - foreach ($response as $line) { - $capabilities = array_merge($capabilities, $line); - } - return $capabilities; - } - - /** - * Examine and select have the same response. The common code for both - * is in this method - * - * @param string $command can be 'EXAMINE' or 'SELECT' and this is used as command - * @param string $box which folder to change to or examine - * @return bool|array false if error, array with returned information - * otherwise (flags, exists, recent, uidvalidity) - * @throws ExceptionInterface - */ - public function examineOrSelect($command = 'EXAMINE', $box = 'INBOX') - { - $tag = null; // define $tag variable before first use - $this->sendRequest($command, [$this->escapeString($box)], $tag); - - $result = []; - $tokens = null; // define $tokens variable before first use - while (! $this->readLine($tokens, $tag)) { - if ($tokens[0] == 'FLAGS') { - array_shift($tokens); - $result['flags'] = $tokens; - continue; - } - switch ($tokens[1]) { - case 'EXISTS': - case 'RECENT': - $result[strtolower($tokens[1])] = $tokens[0]; - break; - case '[UIDVALIDITY': - $result['uidvalidity'] = (int) $tokens[2]; - break; - default: - // ignore - } - } - - if ($tokens[0] != 'OK') { - return false; - } - return $result; - } - - /** - * change folder - * - * @param string $box change to this folder - * @return bool|array see examineOrselect() - * @throws ExceptionInterface - */ - public function select($box = 'INBOX') - { - return $this->examineOrSelect('SELECT', $box); - } - - /** - * examine folder - * - * @param string $box examine this folder - * @return bool|array see examineOrselect() - * @throws ExceptionInterface - */ - public function examine($box = 'INBOX') - { - return $this->examineOrSelect('EXAMINE', $box); - } - - /** - * fetch one or more items of one or more messages - * - * @param string|array $items items to fetch from message(s) as string (if only one item) - * or array of strings - * @param int|array $from message for items or start message if $to !== null - * @param int|null $to if null only one message ($from) is fetched, else it's the - * last message, INF means last message available - * @param bool $uid set to true if passing a unique id - * @throws Exception\RuntimeException - * @return string|array if only one item of one message is fetched it's returned as string - * if items of one message are fetched it's returned as (name => value) - * if one items of messages are fetched it's returned as (msgno => value) - * if items of messages are fetched it's returned as (msgno => (name => value)) - */ - public function fetch($items, $from, $to = null, $uid = false) - { - if (is_array($from)) { - $set = implode(',', $from); - } elseif ($to === null) { - $set = (int) $from; - } elseif ($to === INF) { - $set = (int) $from . ':*'; - } else { - $set = (int) $from . ':' . (int) $to; - } - - $items = (array) $items; - $itemList = $this->escapeList($items); - - $tag = null; // define $tag variable before first use - $this->sendRequest(($uid ? 'UID ' : '') . 'FETCH', [$set, $itemList], $tag); - - $result = []; - $tokens = null; // define $tokens variable before first use - while (! $this->readLine($tokens, $tag)) { - // ignore other responses - if ($tokens[1] != 'FETCH') { - continue; - } - - // find array key of UID value; try the last elements, or search for it - if ($uid) { - $count = count($tokens[2]); - if ($tokens[2][$count - 2] == 'UID') { - $uidKey = $count - 1; - } else { - $uidKey = array_search('UID', $tokens[2]) + 1; - } - } - - // ignore other messages - if ($to === null && ! is_array($from) && ($uid ? $tokens[2][$uidKey] != $from : $tokens[0] != $from)) { - continue; - } - - // if we only want one item we return that one directly - if (count($items) == 1) { - if ($tokens[2][0] == $items[0]) { - $data = $tokens[2][1]; - } elseif ($uid && $tokens[2][2] == $items[0]) { - $data = $tokens[2][3]; - } else { - // maybe the server send an other field we didn't wanted - $count = count($tokens[2]); - // we start with 2, because 0 was already checked - for ($i = 2; $i < $count; $i += 2) { - if ($tokens[2][$i] != $items[0]) { - continue; - } - $data = $tokens[2][$i + 1]; - break; - } - } - } else { - $data = []; - while (key($tokens[2]) !== null) { - $data[current($tokens[2])] = next($tokens[2]); - next($tokens[2]); - } - } - - // if we want only one message we can ignore everything else and just return - if ($to === null && ! is_array($from) && ($uid ? $tokens[2][$uidKey] == $from : $tokens[0] == $from)) { - // we still need to read all lines - // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedWhile - while (! $this->readLine($tokens, $tag)) { - } - return $data; - } - $result[$tokens[0]] = $data; - } - - if ($to === null && ! is_array($from)) { - throw new Exception\RuntimeException('the single id was not found in response'); - } - - return $result; - } - - /** - * get mailbox list - * - * this method can't be named after the IMAP command 'LIST', as list is a reserved keyword - * - * @param string $reference mailbox reference for list - * @param string $mailbox mailbox name match with wildcards - * @return array mailboxes that matched $mailbox as array(globalName => array('delim' => .., 'flags' => ..)) - * @throws ExceptionInterface - */ - public function listMailbox($reference = '', $mailbox = '*') - { - $result = []; - $list = $this->requestAndResponse('LIST', $this->escapeString($reference, $mailbox)); - if (! $list || $list === true) { - return $result; - } - - foreach ($list as $item) { - if (count($item) != 4 || $item[0] != 'LIST') { - continue; - } - $result[$item[3]] = ['delim' => $item[2], 'flags' => $item[1]]; - } - - return $result; - } - - /** - * set flags - * - * @param array $flags flags to set, add or remove - see $mode - * @param int $from message for items or start message if $to !== null - * @param int|null $to if null only one message ($from) is fetched, else it's the - * last message, INF means last message available - * @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given - * @param bool $silent if false the return values are the new flags for the wanted messages - * @return bool|array new flags if $silent is false, else true or false depending on success - * @throws ExceptionInterface - */ - public function store(array $flags, $from, $to = null, $mode = null, $silent = true) - { - $item = 'FLAGS'; - if ($mode == '+' || $mode == '-') { - $item = $mode . $item; - } - if ($silent) { - $item .= '.SILENT'; - } - - $flags = $this->escapeList($flags); - $set = (int) $from; - if ($to !== null) { - $set .= ':' . ($to == INF ? '*' : (int) $to); - } - - $result = $this->requestAndResponse('STORE', [$set, $item, $flags], $silent); - - if ($silent) { - return (bool) $result; - } - - $tokens = $result; - $result = []; - foreach ($tokens as $token) { - if ($token[1] != 'FETCH' || $token[2][0] != 'FLAGS') { - continue; - } - $result[$token[0]] = $token[2][1]; - } - - return $result; - } - - /** - * append a new message to given folder - * - * @param string $folder name of target folder - * @param string $message full message content - * @param array $flags flags for new message - * @param string $date date for new message - * @return bool success - * @throws ExceptionInterface - */ - public function append($folder, $message, $flags = null, $date = null) - { - $tokens = []; - $tokens[] = $this->escapeString($folder); - if ($flags !== null) { - $tokens[] = $this->escapeList($flags); - } - if ($date !== null) { - $tokens[] = $this->escapeString($date); - } - $tokens[] = $this->escapeString($message); - - return $this->requestAndResponse('APPEND', $tokens, true); - } - - /** - * copy message set from current folder to other folder - * - * @param string $folder destination folder - * @param int $from - * @param int|null $to if null only one message ($from) is fetched, else it's the - * last message, INF means last message available - * @return bool success - */ - public function copy($folder, $from, $to = null) - { - $set = (string) $from; - if ($to !== null) { - $set .= ':' . ($to == INF ? '*' : (int) $to); - } - - return $this->requestAndResponse('COPY', [$set, $this->escapeString($folder)], true); - } - - /** - * create a new folder (and parent folders if needed) - * - * @param string $folder folder name - * @return bool success - */ - public function create($folder) - { - return $this->requestAndResponse('CREATE', [$this->escapeString($folder)], true); - } - - /** - * rename an existing folder - * - * @param string $old old name - * @param string $new new name - * @return bool success - */ - public function rename($old, $new) - { - return $this->requestAndResponse('RENAME', $this->escapeString($old, $new), true); - } - - /** - * remove a folder - * - * @param string $folder folder name - * @return bool success - */ - public function delete($folder) - { - return $this->requestAndResponse('DELETE', [$this->escapeString($folder)], true); - } - - /** - * subscribe to a folder - * - * @param string $folder folder name - * @return bool success - */ - public function subscribe($folder) - { - return $this->requestAndResponse('SUBSCRIBE', [$this->escapeString($folder)], true); - } - - /** - * permanently remove messages - * - * @return bool success - */ - public function expunge() - { - // TODO: parse response? - return $this->requestAndResponse('EXPUNGE'); - } - - /** - * send noop - * - * @return bool success - */ - public function noop() - { - // TODO: parse response - return $this->requestAndResponse('NOOP'); - } - - /** - * do a search request - * - * This method is currently marked as internal as the API might change and is not - * safe if you don't take precautions. - * - * @param array $params - * @return array message ids - */ - public function search(array $params) - { - $response = $this->requestAndResponse('SEARCH', $params); - if (! $response) { - return $response; - } - - foreach ($response as $ids) { - if ($ids[0] == 'SEARCH') { - array_shift($ids); - return $ids; - } - } - return []; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Pop3.php b/lib/laminas/laminas-mail/src/Protocol/Pop3.php deleted file mode 100644 index 5c6ee46a9..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Pop3.php +++ /dev/null @@ -1,419 +0,0 @@ -setNoValidateCert($novalidatecert); - - if ($host) { - $this->connect($host, $port, $ssl); - } - } - - /** - * Public destructor - */ - public function __destruct() - { - $this->logout(); - } - - /** - * Open connection to POP3 server - * - * @param string $host hostname or IP address of POP3 server - * @param int|null $port of POP3 server, default is 110 (995 for ssl) - * @param string|bool $ssl use 'SSL', 'TLS' or false - * @throws Exception\RuntimeException - * @return string welcome message - */ - public function connect($host, $port = null, $ssl = false) - { - $transport = 'tcp'; - $isTls = false; - - if ($ssl) { - $ssl = strtolower($ssl); - } - - switch ($ssl) { - case 'ssl': - $transport = 'ssl'; - if (! $port) { - $port = 995; - } - break; - case 'tls': - $isTls = true; - // break intentionally omitted - default: - if (! $port) { - $port = 110; - } - } - - $this->socket = $this->setupSocket($transport, $host, $port, self::TIMEOUT_CONNECTION); - - $welcome = $this->readResponse(); - - strtok($welcome, '<'); - $this->timestamp = strtok('>'); - if (! strpos($this->timestamp, '@')) { - $this->timestamp = null; - } else { - $this->timestamp = '<' . $this->timestamp . '>'; - } - - if ($isTls) { - $this->request('STLS'); - $result = stream_socket_enable_crypto($this->socket, true, $this->getCryptoMethod()); - if (! $result) { - throw new Exception\RuntimeException('cannot enable TLS'); - } - } - - return $welcome; - } - - /** - * Send a request - * - * @param string $request your request without newline - * @throws Exception\RuntimeException - */ - public function sendRequest($request) - { - ErrorHandler::start(); - $result = fwrite($this->socket, $request . "\r\n"); - $error = ErrorHandler::stop(); - if (! $result) { - throw new Exception\RuntimeException('send failed - connection closed?', 0, $error); - } - } - - /** - * read a response - * - * @param bool $multiline response has multiple lines and should be read until "." - * @throws Exception\RuntimeException - * @return string response - */ - public function readResponse($multiline = false) - { - $response = $this->readRemoteResponse(); - - if ($response->status() != '+OK') { - throw new Exception\RuntimeException('last request failed'); - } - - $message = $response->message(); - - if ($multiline) { - $message = ''; - $line = fgets($this->socket); - while ($line && rtrim($line, "\r\n") != '.') { - if ($line[0] == '.') { - $line = substr($line, 1); - } - $message .= $line; - $line = fgets($this->socket); - } - } - - return $message; - } - - /** - * read a response - * return extracted status / message from response - - * @throws Exception\RuntimeException - */ - protected function readRemoteResponse(): Response - { - ErrorHandler::start(); - $result = fgets($this->socket); - $error = ErrorHandler::stop(); - if (! is_string($result)) { - throw new Exception\RuntimeException('read failed - connection closed?', 0, $error); - } - - $result = trim($result); - if (strpos($result, ' ')) { - [$status, $message] = explode(' ', $result, 2); - } else { - $status = $result; - $message = ''; - } - - return new Response($status, $message); - } - - /** - * Send request and get response - * - * @see sendRequest() - * @see readResponse() - * - * @param string $request request - * @param bool $multiline multiline response? - * @return string result from readResponse() - */ - public function request($request, $multiline = false) - { - $this->sendRequest($request); - return $this->readResponse($multiline); - } - - /** - * End communication with POP3 server (also closes socket) - */ - public function logout() - { - if ($this->socket) { - try { - $this->request('QUIT'); - } catch (Exception\ExceptionInterface) { - // ignore error - we're closing the socket anyway - } - - fclose($this->socket); - $this->socket = null; - } - } - - /** - * Get capabilities from POP3 server - * - * @return array list of capabilities - */ - public function capa() - { - $result = $this->request('CAPA', true); - return explode("\n", $result); - } - - /** - * Login to POP3 server. Can use APOP - * - * @param string $user username - * @param string $password password - * @param bool $tryApop should APOP be tried? - */ - public function login($user, $password, $tryApop = true) - { - if ($tryApop && $this->timestamp) { - try { - $this->request("APOP $user " . md5($this->timestamp . $password)); - return; - } catch (Exception\ExceptionInterface) { - // ignore - } - } - - $this->request("USER $user"); - $this->request("PASS $password"); - } - - /** - * Make STAT call for message count and size sum - * - * @param int $messages out parameter with count of messages - * @param int $octets out parameter with size in octets of messages - */ - public function status(&$messages, &$octets) - { - $messages = 0; - $octets = 0; - $result = $this->request('STAT'); - - [$messages, $octets] = explode(' ', $result); - } - - /** - * Make LIST call for size of message(s) - * - * @param int|null $msgno number of message, null for all - * @return int|array size of given message or list with array(num => size) - */ - public function getList($msgno = null) - { - if ($msgno !== null) { - $result = $this->request("LIST $msgno"); - - [, $result] = explode(' ', $result); - return (int) $result; - } - - $result = $this->request('LIST', true); - $messages = []; - $line = strtok($result, "\n"); - while ($line) { - [$no, $size] = explode(' ', trim($line)); - $messages[(int) $no] = (int) $size; - $line = strtok("\n"); - } - - return $messages; - } - - /** - * Make UIDL call for getting a uniqueid - * - * @param int|null $msgno number of message, null for all - * @return string|array uniqueid of message or list with array(num => uniqueid) - */ - public function uniqueid($msgno = null) - { - if ($msgno !== null) { - $result = $this->request("UIDL $msgno"); - - [, $result] = explode(' ', $result); - return $result; - } - - $result = $this->request('UIDL', true); - - $result = explode("\n", $result); - $messages = []; - foreach ($result as $line) { - if (! $line) { - continue; - } - [$no, $id] = explode(' ', trim($line), 2); - $messages[(int) $no] = $id; - } - - return $messages; - } - - /** - * Make TOP call for getting headers and maybe some body lines - * This method also sets hasTop - before it it's not known if top is supported - * - * The fallback makes normal RETR call, which retrieves the whole message. Additional - * lines are not removed. - * - * @param int $msgno number of message - * @param int $lines number of wanted body lines (empty line is inserted after header lines) - * @param bool $fallback fallback with full retrieve if top is not supported - * @throws Exception\RuntimeException - * @throws Exception\ExceptionInterface - * @return string message headers with wanted body lines - */ - public function top($msgno, $lines = 0, $fallback = false) - { - if ($this->hasTop === false) { - if ($fallback) { - return $this->retrieve($msgno); - } - - throw new Exception\RuntimeException('top not supported and no fallback wanted'); - } - $this->hasTop = true; - - $lines = ! $lines || $lines < 1 ? 0 : (int) $lines; - - try { - $result = $this->request("TOP $msgno $lines", true); - } catch (Exception\ExceptionInterface $e) { - $this->hasTop = false; - if ($fallback) { - $result = $this->retrieve($msgno); - } else { - throw $e; - } - } - - return $result; - } - - /** - * Make a RETR call for retrieving a full message with headers and body - * - * @param int $msgno message number - * @return string message - */ - public function retrieve($msgno) - { - return $this->request("RETR $msgno", true); - } - - /** - * Make a NOOP call, maybe needed for keeping the server happy - */ - public function noop() - { - $this->request('NOOP'); - } - - /** - * Make a DELE count to remove a message - * - * @param int $msgno - */ - public function delete($msgno) - { - $this->request("DELE $msgno"); - } - - /** - * Make RSET call, which rollbacks delete requests - */ - public function undelete() - { - $this->request('RSET'); - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Pop3/Response.php b/lib/laminas/laminas-mail/src/Protocol/Pop3/Response.php deleted file mode 100644 index 41c0eb5bb..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Pop3/Response.php +++ /dev/null @@ -1,35 +0,0 @@ -status = $status; - $this->message = $message; - } - - public function status(): string - { - return $this->status; - } - - public function message(): string - { - return $this->message; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Pop3/Xoauth2/Microsoft.php b/lib/laminas/laminas-mail/src/Protocol/Pop3/Xoauth2/Microsoft.php deleted file mode 100644 index 74d093dc7..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Pop3/Xoauth2/Microsoft.php +++ /dev/null @@ -1,34 +0,0 @@ -sendRequest(self::AUTH_INITIALIZE_REQUEST); - - $response = $this->readRemoteResponse(); - - if ($response->status() != self::AUTH_RESPONSE_INITIALIZED_OK) { - throw new RuntimeException($response->message()); - } - - $this->request(Xoauth2::encodeXoauth2Sasl($user, $password)); - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/ProtocolTrait.php b/lib/laminas/laminas-mail/src/Protocol/ProtocolTrait.php deleted file mode 100644 index 60d246c42..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/ProtocolTrait.php +++ /dev/null @@ -1,122 +0,0 @@ -novalidatecert = $novalidatecert; - return $this; - } - - /** - * Should we validate SSL certificate? - */ - public function validateCert(): bool - { - return ! $this->novalidatecert; - } - - /** - * Prepare socket options - * - * @return array - */ - private function prepareSocketOptions(): array - { - return $this->novalidatecert - ? [ - 'ssl' => [ - 'verify_peer_name' => false, - 'verify_peer' => false, - ], - ] - : []; - } - - /** - * Setup connection socket - * - * @param string $host hostname or IP address of IMAP server - * @param int|null $port of IMAP server, default is 143 (993 for ssl) - * @param int $timeout timeout in seconds for initiating session - * @return resource The socket created. - * @throws Exception\RuntimeException If unable to connect to host. - */ - protected function setupSocket( - string $transport, - string $host, - ?int $port, - int $timeout - ) { - ErrorHandler::start(); - $socket = stream_socket_client( - sprintf('%s://%s:%d', $transport, $host, $port), - $errno, - $errstr, - $timeout, - STREAM_CLIENT_CONNECT, - stream_context_create($this->prepareSocketOptions()) - ); - $error = ErrorHandler::stop(); - - if (! $socket) { - throw new Exception\RuntimeException(sprintf( - 'cannot connect to host%s', - $error ? sprintf('; error = %s (errno = %d )', $error->getMessage(), $error->getCode()) : '' - ), 0, $error); - } - - if (false === stream_set_timeout($socket, $timeout)) { - throw new Exception\RuntimeException('Could not set stream timeout'); - } - - return $socket; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Smtp.php b/lib/laminas/laminas-mail/src/Protocol/Smtp.php deleted file mode 100644 index f35ca72c0..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Smtp.php +++ /dev/null @@ -1,521 +0,0 @@ -secure = 'tls'; - break; - - case 'ssl': - $this->transport = 'ssl'; - $this->secure = 'ssl'; - if ($port === null) { - $port = 465; - } - break; - - case '': - // fall-through - case 'none': - break; - - default: - throw new Exception\InvalidArgumentException($config['ssl'] . ' is unsupported SSL type'); - } - } - - if (array_key_exists('use_complete_quit', $config)) { - $this->setUseCompleteQuit($config['use_complete_quit']); - } - - // If no port has been specified then check the master PHP ini file. Defaults to 25 if the ini setting is null. - if ($port === null) { - if (($port = ini_get('smtp_port')) == '') { - $port = 25; - } - } - - if (array_key_exists('novalidatecert', $config)) { - $this->setNoValidateCert($config['novalidatecert']); - } - - parent::__construct($host, $port); - } - - /** - * Set whether or not send QUIT command - * - * @param bool $useCompleteQuit use complete quit - * @return bool - */ - public function setUseCompleteQuit($useCompleteQuit) - { - return $this->useCompleteQuit = (bool) $useCompleteQuit; - } - - /** - * Read $data as lines terminated by "\n" - * - * @return Generator|string[] - */ - private static function chunkedReader(string $data, int $chunkSize = 4096): Generator - { - if (($fp = fopen("php://temp", "r+")) === false) { - throw new Exception\RuntimeException('cannot fopen'); - } - if (fwrite($fp, $data) === false) { - throw new Exception\RuntimeException('cannot fwrite'); - } - rewind($fp); - - $line = null; - while (($buffer = fgets($fp, $chunkSize)) !== false) { - $line .= $buffer; - - // This is optimization to avoid calling length() in a loop. - // We need to match a condition that is when: - // 1. maximum was read from fgets, which is $chunkSize-1 - // 2. last byte of the buffer is not \n - // - // to access last byte of buffer, we can do - // - $buffer[strlen($buffer)-1] - // and when maximum is read from fgets, then: - // - strlen($buffer) === $chunkSize-1 - // - strlen($buffer)-1 === $chunkSize-2 - // which means this is also true: - // - $buffer[strlen($buffer)-1] === $buffer[$chunkSize-2] - // - // the null coalesce works, as string offset can never be null - $lastByte = $buffer[$chunkSize - 2] ?? null; - - // partial read, continue loop to read again to complete the line - // compare \n first as that's usually false - if ($lastByte !== "\n" && $lastByte !== null) { - continue; - } - - yield $line; - $line = null; - } - - if ($line !== null) { - yield $line; - } - - fclose($fp); - } - - /** - * Whether or not send QUIT command - * - * @return bool - */ - public function useCompleteQuit() - { - return $this->useCompleteQuit; - } - - /** - * Connect to the server with the parameters given in the constructor. - * - * @return bool - */ - public function connect() - { - $this->socket = $this->setupSocket( - $this->transport, - $this->host, - $this->port, - self::TIMEOUT_CONNECTION - ); - return true; - } - - /** - * Initiate HELO/EHLO sequence and set flag to indicate valid smtp session - * - * @param string $host The client hostname or IP address (default: 127.0.0.1) - * @throws Exception\RuntimeException - */ - public function helo($host = '127.0.0.1') - { - // Respect RFC 2821 and disallow HELO attempts if session is already initiated. - if ($this->sess === true) { - throw new Exception\RuntimeException('Cannot issue HELO to existing session'); - } - - // Validate client hostname - if (! $this->validHost->isValid($host)) { - throw new Exception\RuntimeException(implode(', ', $this->validHost->getMessages())); - } - - // Initiate helo sequence - $this->_expect(220, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 - $this->ehlo($host); - - // If a TLS session is required, commence negotiation - if ($this->secure == 'tls') { - $this->_send('STARTTLS'); - $this->_expect(220, 180); - if (! stream_socket_enable_crypto($this->socket, true, $this->getCryptoMethod())) { - throw new Exception\RuntimeException('Unable to connect via TLS'); - } - $this->ehlo($host); - } - - $this->startSession(); - $this->auth(); - } - - /** - * Returns the perceived session status - * - * @return bool - */ - public function hasSession() - { - return $this->sess; - } - - /** - * Send EHLO or HELO depending on capabilities of smtp host - * - * @param string $host The client hostname or IP address (default: 127.0.0.1) - * @throws Exception\ExceptionInterface - */ - protected function ehlo($host) - { - // Support for older, less-compliant remote servers. Tries multiple attempts of EHLO or HELO. - try { - $this->_send('EHLO ' . $host); - $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 - } catch (Exception\ExceptionInterface) { - $this->_send('HELO ' . $host); - $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 - } - } - - /** - * Issues MAIL command - * - * @param string $from Sender mailbox - * @throws Exception\RuntimeException - */ - public function mail($from) - { - if ($this->sess !== true) { - throw new Exception\RuntimeException('A valid session has not been started'); - } - - $this->_send('MAIL FROM:<' . $from . '>'); - $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 - - // Set mail to true, clear recipients and any existing data flags as per 4.1.1.2 of RFC 2821 - $this->mail = true; - $this->rcpt = false; - $this->data = false; - } - - /** - * Issues RCPT command - * - * @param string $to Receiver(s) mailbox - * @throws Exception\RuntimeException - */ - public function rcpt($to) - { - if ($this->mail !== true) { - throw new Exception\RuntimeException('No sender reverse path has been supplied'); - } - - // Set rcpt to true, as per 4.1.1.3 of RFC 2821 - $this->_send('RCPT TO:<' . $to . '>'); - $this->_expect([250, 251], 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 - $this->rcpt = true; - } - - /** - * Issues DATA command - * - * @param string $data - * @throws Exception\RuntimeException - */ - public function data($data) - { - // Ensure recipients have been set - if ($this->rcpt !== true) { // Per RFC 2821 3.3 (page 18) - throw new Exception\RuntimeException('No recipient forward path has been supplied'); - } - - $this->_send('DATA'); - $this->_expect(354, 120); // Timeout set for 2 minutes as per RFC 2821 4.5.3.2 - - $reader = self::chunkedReader($data); - foreach ($reader as $line) { - $line = rtrim($line, "\r\n"); - if (isset($line[0]) && $line[0] === '.') { - // Escape lines prefixed with a '.' - $line = '.' . $line; - } - - if (strlen($line) > self::SMTP_LINE_LIMIT) { - // Long lines are "folded" by inserting "" - // https://tools.ietf.org/html/rfc5322#section-2.2.3 - // Add "-1" to stay within limits, - // because Headers::FOLDING includes a byte for space character after \r\n - $chunks = chunk_split($line, self::SMTP_LINE_LIMIT - 1, Headers::FOLDING); - $line = substr($chunks, 0, -strlen(Headers::FOLDING)); - } - - $this->_send($line); - } - - $this->_send('.'); - $this->_expect(250, 600); // Timeout set for 10 minutes as per RFC 2821 4.5.3.2 - $this->data = true; - } - - /** - * Issues the RSET command end validates answer - * - * Can be used to restore a clean smtp communication state when a - * transaction has been cancelled or commencing a new transaction. - */ - public function rset() - { - $this->_send('RSET'); - // MS ESMTP doesn't follow RFC, see https://zendframework.com/issues/browse/ZF-1377 - $this->_expect([250, 220]); - - $this->mail = false; - $this->rcpt = false; - $this->data = false; - } - - /** - * Issues the NOOP command end validates answer - * - * Not used by Laminas\Mail, could be used to keep a connection alive or check if it is still open. - */ - public function noop() - { - $this->_send('NOOP'); - $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 - } - - /** - * Issues the VRFY command end validates answer - * - * Not used by Laminas\Mail. - * - * @param string $user User Name or eMail to verify - */ - public function vrfy($user) - { - $this->_send('VRFY ' . $user); - $this->_expect([250, 251, 252], 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 - } - - /** - * Issues the QUIT command and clears the current session - */ - public function quit() - { - if ($this->sess) { - $this->auth = false; - - if ($this->useCompleteQuit()) { - $this->_send('QUIT'); - $this->_expect(221, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 - } - - $this->stopSession(); - } - } - - /** - * Default authentication method - * - * This default method is implemented by AUTH adapters to properly authenticate to a remote host. - * - * @throws Exception\RuntimeException - */ - public function auth() - { - if ($this->auth === true) { - throw new Exception\RuntimeException('Already authenticated for this session'); - } - } - - /** - * Closes connection - */ - public function disconnect() - { - $this->_disconnect(); - } - - /** - * Disconnect from remote host and free resource - */ - // @codingStandardsIgnoreLine PSR2.Methods.MethodDeclaration.Underscore - protected function _disconnect() - { - // Make sure the session gets closed - $this->quit(); - parent::_disconnect(); - } - - /** - * Start mail session - */ - protected function startSession() - { - $this->sess = true; - } - - /** - * Stop mail session - */ - protected function stopSession() - { - $this->sess = false; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php b/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php deleted file mode 100644 index 3435cf7ce..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Crammd5.php +++ /dev/null @@ -1,131 +0,0 @@ -setUsername($config['username']); - } - if (isset($config['password'])) { - $this->setPassword($config['password']); - } - } - - // Call parent with original arguments - parent::__construct($host, $port, $origConfig); - } - - /** - * Performs CRAM-MD5 authentication with supplied credentials - */ - public function auth() - { - // Ensure AUTH has not already been initiated. - parent::auth(); - - $this->_send('AUTH CRAM-MD5'); - $challenge = $this->_expect(334); - $challenge = base64_decode($challenge); - $digest = $this->hmacMd5($this->getPassword(), $challenge); - $this->_send(base64_encode($this->getUsername() . ' ' . $digest)); - $this->_expect(235); - $this->auth = true; - } - - /** - * Set value for username - * - * @param string $username - * @return Crammd5 - */ - public function setUsername($username) - { - $this->username = $username; - return $this; - } - - /** - * Get username - * - * @return string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Set value for password - * - * @param string $password - * @return Crammd5 - */ - public function setPassword($password) - { - $this->password = $password; - return $this; - } - - /** - * Get password - * - * @return string - */ - public function getPassword() - { - return $this->password; - } - - /** - * Prepare CRAM-MD5 response to server's ticket - * - * @param string $key Challenge key (usually password) - * @param string $data Challenge data - * @param int $block Length of blocks (deprecated; unused) - * @return string - */ - protected function hmacMd5($key, $data, $block = 64) - { - return Hmac::compute($key, 'md5', $data); - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php b/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php deleted file mode 100644 index c7be3c6ed..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Login.php +++ /dev/null @@ -1,121 +0,0 @@ -setUsername($config['username']); - } - if (isset($config['password'])) { - $this->setPassword($config['password']); - } - } - - // Call parent with original arguments - parent::__construct($host, $port, $origConfig); - } - - /** - * Perform LOGIN authentication with supplied credentials - */ - public function auth() - { - // Ensure AUTH has not already been initiated. - parent::auth(); - - $this->_send('AUTH LOGIN'); - $this->_expect(334); - $this->_send(base64_encode($this->getUsername())); - $this->_expect(334); - $this->_send(base64_encode($this->getPassword())); - $this->_expect(235); - $this->auth = true; - } - - /** - * Set value for username - * - * @param string $username - * @return Login - */ - public function setUsername($username) - { - $this->username = $username; - return $this; - } - - /** - * Get username - * - * @return string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Set value for password - * - * @param string $password - * @return Login - */ - public function setPassword($password) - { - $this->password = $password; - return $this; - } - - /** - * Get password - * - * @return string - */ - public function getPassword() - { - return $this->password; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php b/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php deleted file mode 100644 index 6e3091e5c..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Plain.php +++ /dev/null @@ -1,119 +0,0 @@ -setUsername($config['username']); - } - if (isset($config['password'])) { - $this->setPassword($config['password']); - } - } - - // Call parent with original arguments - parent::__construct($host, $port, $origConfig); - } - - /** - * Perform PLAIN authentication with supplied credentials - */ - public function auth() - { - // Ensure AUTH has not already been initiated. - parent::auth(); - - $this->_send('AUTH PLAIN'); - $this->_expect(334); - $this->_send(base64_encode("\0" . $this->getUsername() . "\0" . $this->getPassword())); - $this->_expect(235); - $this->auth = true; - } - - /** - * Set value for username - * - * @param string $username - * @return Plain - */ - public function setUsername($username) - { - $this->username = $username; - return $this; - } - - /** - * Get username - * - * @return string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Set value for password - * - * @param string $password - * @return Plain - */ - public function setPassword($password) - { - $this->password = $password; - return $this; - } - - /** - * Get password - * - * @return string - */ - public function getPassword() - { - return $this->password; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Xoauth2.php b/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Xoauth2.php deleted file mode 100644 index 34b462970..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Smtp/Auth/Xoauth2.php +++ /dev/null @@ -1,123 +0,0 @@ -setUsername((string) $config['username']); - } - if (isset($config['access_token'])) { - $this->setAccessToken((string) $config['access_token']); - } - } - - // Call parent with original arguments - parent::__construct($host, $port, $origConfig); - } - - /** - * Perform XOAUTH2 authentication with supplied credentials - * - * @return void - */ - public function auth() - { - // Ensure AUTH has not already been initiated. - parent::auth(); - - $this->_send('AUTH XOAUTH2'); - $this->_expect('334'); - $this->_send(Xoauth2AuthEncoder::encodeXoauth2Sasl($this->getUsername(), $this->getAccessToken())); - $this->_expect('235'); - $this->auth = true; - } - - /** - * Set value for username - * - * @param string $username - * @return Xoauth2 - */ - public function setUsername($username) - { - $this->username = $username; - return $this; - } - - /** - * Get username - * - * @return string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Set value for access token - * - * @param string $token - * @return Xoauth2 - */ - public function setAccessToken($token) - { - $this->accessToken = $token; - return $this; - } - - /** - * Get access token - * - * @return string - */ - public function getAccessToken() - { - return $this->accessToken; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php b/lib/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php deleted file mode 100644 index 80225ca69..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/SmtpPluginManager.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @final - */ -class SmtpPluginManager extends AbstractPluginManager -{ - /** - * Service aliases - * - * @var array - */ - protected $aliases = [ - 'crammd5' => Smtp\Auth\Crammd5::class, - 'cramMd5' => Smtp\Auth\Crammd5::class, - 'CramMd5' => Smtp\Auth\Crammd5::class, - 'cramMD5' => Smtp\Auth\Crammd5::class, - 'CramMD5' => Smtp\Auth\Crammd5::class, - 'login' => Smtp\Auth\Login::class, - 'Login' => Smtp\Auth\Login::class, - 'plain' => Smtp\Auth\Plain::class, - 'Plain' => Smtp\Auth\Plain::class, - 'xoauth2' => Smtp\Auth\Xoauth2::class, - 'Xoauth2' => Smtp\Auth\Xoauth2::class, - 'smtp' => Smtp::class, - 'Smtp' => Smtp::class, - 'SMTP' => Smtp::class, - // Legacy Zend Framework aliases - 'Zend\Mail\Protocol\Smtp\Auth\Crammd5' => Smtp\Auth\Crammd5::class, - 'Zend\Mail\Protocol\Smtp\Auth\Login' => Smtp\Auth\Login::class, - 'Zend\Mail\Protocol\Smtp\Auth\Plain' => Smtp\Auth\Plain::class, - 'Zend\Mail\Protocol\Smtp' => Smtp::class, - // v2 normalized FQCNs - 'zendmailprotocolsmtpauthcrammd5' => Smtp\Auth\Crammd5::class, - 'zendmailprotocolsmtpauthlogin' => Smtp\Auth\Login::class, - 'zendmailprotocolsmtpauthplain' => Smtp\Auth\Plain::class, - 'zendmailprotocolsmtp' => Smtp::class, - 'laminasmailprotocolsmtpauthcrammd5' => Smtp\Auth\Crammd5::class, - 'laminasmailprotocolsmtpauthlogin' => Smtp\Auth\Login::class, - 'laminasmailprotocolsmtpauthplain' => Smtp\Auth\Plain::class, - 'laminasmailprotocolsmtp' => Smtp::class, - ]; - - /** - * Service factories - * - * @var FactoriesConfigurationType - */ - protected $factories = [ - Smtp\Auth\Crammd5::class => InvokableFactory::class, - Smtp\Auth\Login::class => InvokableFactory::class, - Smtp\Auth\Plain::class => InvokableFactory::class, - Smtp\Auth\Xoauth2::class => InvokableFactory::class, - Smtp::class => InvokableFactory::class, - ]; - - /** - * Plugins must be an instance of the Smtp class - * - * @var class-string - */ - protected $instanceOf = Smtp::class; - - /** - * Validate a retrieved plugin instance (v3). - * - * {@inheritDoc} - */ - public function validate(mixed $instance) - { - if (! $instance instanceof $this->instanceOf) { - throw new InvalidServiceException(sprintf( - 'Plugin of type %s is invalid; must extend %s', - is_object($instance) ? $instance::class : gettype($instance), - $this->instanceOf - )); - } - } - - /** - * Validate a retrieved plugin instance (v2). - * - * @deprecated - * - * @param object $plugin - * @throws Exception\InvalidArgumentException - */ - public function validatePlugin(mixed $plugin) - { - try { - $this->validate($plugin); - } catch (InvalidServiceException $e) { - throw new Exception\InvalidArgumentException( - $e->getMessage(), - $e->getCode(), - $e - ); - } - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/SmtpPluginManagerFactory.php b/lib/laminas/laminas-mail/src/Protocol/SmtpPluginManagerFactory.php deleted file mode 100644 index f63b85098..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/SmtpPluginManagerFactory.php +++ /dev/null @@ -1,57 +0,0 @@ -creationOptions); - } - - /** - * laminas-servicemanager v2 support for invocation options. - * - * @psalm-param ServiceManagerConfiguration $options - * @return void - */ - public function setCreationOptions(array $options) - { - $this->creationOptions = $options; - } -} diff --git a/lib/laminas/laminas-mail/src/Protocol/Xoauth2/Xoauth2.php b/lib/laminas/laminas-mail/src/Protocol/Xoauth2/Xoauth2.php deleted file mode 100644 index fa3d5b883..000000000 --- a/lib/laminas/laminas-mail/src/Protocol/Xoauth2/Xoauth2.php +++ /dev/null @@ -1,32 +0,0 @@ - true, - 'delete' => false, - 'create' => false, - 'top' => false, - 'fetchPart' => true, - 'flags' => false, - ]; - - /** - * current iteration position - * - * @var int - */ - protected $iterationPos = 0; - - /** - * maximum iteration position (= message count) - * - * @var null|int - */ - protected $iterationMax; - - /** - * used message class, change it in an extended class to extend the returned message class - * - * @var class-string - */ - protected $messageClass = Message::class; - - /** - * Getter for has-properties. The standard has properties - * are: hasFolder, hasUniqueid, hasDelete, hasCreate, hasTop - * - * The valid values for the has-properties are: - * - true if a feature is supported - * - false if a feature is not supported - * - null is it's not yet known or it can't be know if a feature is supported - * - * @param string $var property name - * @throws Exception\InvalidArgumentException - * @return null|bool supported or not - */ - public function __get($var) - { - if (str_starts_with($var, 'has')) { - $var = strtolower(substr($var, 3)); - return $this->has[$var] ?? null; - } - - throw new Exception\InvalidArgumentException($var . ' not found'); - } - - /** - * Get a full list of features supported by the specific mail lib and the server - * - * @return array list of features as array(feature_name => true|false[|null]) - */ - public function getCapabilities() - { - return $this->has; - } - - /** - * Count messages messages in current box/folder - * - * @return int number of messages - * @throws Exception\ExceptionInterface - */ - abstract public function countMessages(); - - /** - * Get a list of messages with number and size - * - * @param int $id number of message - * @return int|array size of given message of list with all messages as array(num => size) - */ - abstract public function getSize($id = 0); - - /** - * Get a message with headers and body - * - * @param int $id number of message - * @return Message\MessageInterface - */ - abstract public function getMessage($id); - - /** - * Get raw header of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message header - * @param int $topLines include this many lines with header (after an empty line) - * @return string raw header - */ - abstract public function getRawHeader($id, $part = null, $topLines = 0); - - /** - * Get raw content of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message content - * @return string raw content - */ - abstract public function getRawContent($id, $part = null); - - /** - * Create instance with parameters - * - * @param array $params mail reader specific parameters - * @throws Exception\ExceptionInterface - */ - abstract public function __construct($params); - - /** - * Destructor calls close() and therefore closes the resource. - */ - public function __destruct() - { - $this->close(); - } - - /** - * Close resource for mail lib. If you need to control, when the resource - * is closed. Otherwise the destructor would call this. - */ - abstract public function close(); - - /** - * Keep the resource alive. - */ - abstract public function noop(); - - /** - * delete a message from current box/folder - * - * @param int $id message number - */ - abstract public function removeMessage($id); - - /** - * get unique id for one or all messages - * - * if storage does not support unique ids it's the same as the message number - * - * @param int|null $id message number - * @return array|string message number for given message or all messages as array - * @throws Exception\ExceptionInterface - */ - abstract public function getUniqueId($id = null); - - /** - * get a message number from a unique id - * - * I.e. if you have a webmailer that supports deleting messages you should use unique ids - * as parameter and use this method to translate it to message number right before calling removeMessage() - * - * @param string $id unique id - * @return int message number - * @throws Exception\ExceptionInterface - */ - abstract public function getNumberByUniqueId($id); - - // interface implementations follows - - /** - * Countable::count() - * - * @return int - */ - #[ReturnTypeWillChange] - public function count() - { - return $this->countMessages(); - } - - /** - * ArrayAccess::offsetExists() - * - * @param int $id - * @return bool - */ - #[ReturnTypeWillChange] - public function offsetExists($id) - { - try { - if ($this->getMessage($id)) { - return true; - } - } catch (Exception\ExceptionInterface) { - } - - return false; - } - - /** - * ArrayAccess::offsetGet() - * - * @param int $id - * @return Message message object - */ - #[ReturnTypeWillChange] - public function offsetGet($id) - { - return $this->getMessage($id); - } - - /** - * ArrayAccess::offsetSet() - * - * @throws Exception\RuntimeException - */ - #[ReturnTypeWillChange] - public function offsetSet(mixed $id, mixed $value) - { - throw new Exception\RuntimeException('cannot write mail messages via array access'); - } - - /** - * ArrayAccess::offsetUnset() - * - * @param int $id - * @return bool success - */ - #[ReturnTypeWillChange] - public function offsetUnset($id) - { - return $this->removeMessage($id); - } - - /** - * Iterator::rewind() - * - * Rewind always gets the new count from the storage. Thus if you use - * the interfaces and your scripts take long you should use reset() - * from time to time. - */ - #[ReturnTypeWillChange] - public function rewind() - { - $this->iterationMax = $this->countMessages(); - $this->iterationPos = 1; - } - - /** - * Iterator::current() - * - * @return Message current message - */ - #[ReturnTypeWillChange] - public function current() - { - return $this->getMessage($this->iterationPos); - } - - /** - * Iterator::key() - * - * @return int id of current position - */ - #[ReturnTypeWillChange] - public function key() - { - return $this->iterationPos; - } - - /** - * Iterator::next() - */ - #[ReturnTypeWillChange] - public function next() - { - ++$this->iterationPos; - } - - /** - * Iterator::valid() - * - * @return bool - */ - #[ReturnTypeWillChange] - public function valid() - { - if ($this->iterationMax === null) { - $this->iterationMax = $this->countMessages(); - } - return $this->iterationPos && $this->iterationPos <= $this->iterationMax; - } - - /** - * SeekableIterator::seek() - * - * @param int $pos - * @throws Exception\OutOfBoundsException - */ - #[ReturnTypeWillChange] - public function seek($pos) - { - if ($this->iterationMax === null) { - $this->iterationMax = $this->countMessages(); - } - - if ($pos > $this->iterationMax) { - throw new Exception\OutOfBoundsException('this position does not exist'); - } - $this->iterationPos = $pos; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php b/lib/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php deleted file mode 100644 index 856cd626a..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Exception/ExceptionInterface.php +++ /dev/null @@ -1,9 +0,0 @@ - $folders subfolders of - * folder array(localName => \Laminas\Mail\Storage\Folder folder) - */ - public function __construct( - protected $localName, - $globalName = '', - protected $selectable = true, - protected array $folders = [] - ) { - $this->globalName = $globalName ?: $localName; - } - - /** - * implements RecursiveIterator::hasChildren() - * - * @return bool current element has children - */ - #[ReturnTypeWillChange] - public function hasChildren() - { - $current = $this->current(); - return $current && $current instanceof self && ! $current->isLeaf(); - } - - /** - * implements RecursiveIterator::getChildren() - * - * @return Folder same as self::current() - */ - #[ReturnTypeWillChange] - public function getChildren() - { - return $this->current(); - } - - /** - * implements Iterator::valid() - * - * @return bool check if there's a current element - */ - #[ReturnTypeWillChange] - public function valid() - { - return key($this->folders) !== null; - } - - /** - * implements Iterator::next() - */ - #[ReturnTypeWillChange] - public function next() - { - next($this->folders); - } - - /** - * implements Iterator::key() - * - * @return string key/local name of current element - */ - #[ReturnTypeWillChange] - public function key() - { - return key($this->folders); - } - - /** - * implements Iterator::current() - * - * @return Folder current folder - */ - #[ReturnTypeWillChange] - public function current() - { - return current($this->folders); - } - - /** - * implements Iterator::rewind() - */ - #[ReturnTypeWillChange] - public function rewind() - { - reset($this->folders); - } - - /** - * get subfolder named $name - * - * @param string $name wanted subfolder - * @throws Exception\InvalidArgumentException - * @return Folder folder named $folder - */ - public function __get($name) - { - if (! isset($this->folders[$name])) { - throw new Exception\InvalidArgumentException("no subfolder named $name"); - } - - return $this->folders[$name]; - } - - /** - * add or replace subfolder named $name - * - * @param string $name local name of subfolder - * @param Folder $folder instance for new subfolder - */ - public function __set($name, self $folder) - { - $this->folders[$name] = $folder; - } - - /** - * remove subfolder named $name - * - * @param string $name local name of subfolder - */ - public function __unset($name) - { - unset($this->folders[$name]); - } - - /** - * magic method for easy output of global name - * - * @return string global name of folder - */ - public function __toString(): string - { - return (string) $this->getGlobalName(); - } - - /** - * get local name - * - * @return string local name - */ - public function getLocalName() - { - return $this->localName; - } - - /** - * get global name - * - * @return string global name - */ - public function getGlobalName() - { - return $this->globalName; - } - - /** - * is this folder selectable? - * - * @return bool selectable - */ - public function isSelectable() - { - return $this->selectable; - } - - /** - * check if folder has no subfolder - * - * @return bool true if no subfolders - */ - public function isLeaf() - { - return empty($this->folders); - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Folder/FolderInterface.php b/lib/laminas/laminas-mail/src/Storage/Folder/FolderInterface.php deleted file mode 100644 index 426ffc143..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Folder/FolderInterface.php +++ /dev/null @@ -1,35 +0,0 @@ -rootdir = rtrim($dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - - $delim = $params['delim'] ?? '.'; - $this->delim = (string) $delim; - - $folder = $params['folder'] ?? 'INBOX'; - - $this->buildFolderTree(); - $this->selectFolder((string) $folder); - $this->has['top'] = true; - $this->has['flags'] = true; - } - - /** - * find all subfolders and mbox files for folder structure - * - * Result is save in Storage\Folder instances with the root in $this->rootFolder. - * $parentFolder and $parentGlobalName are only used internally for recursion. - * - * @throws Exception\RuntimeException - */ - protected function buildFolderTree() - { - $this->rootFolder = new Storage\Folder('/', '/', false); - $this->rootFolder->INBOX = new Storage\Folder('INBOX', 'INBOX', true); - - ErrorHandler::start(E_WARNING); - $dh = opendir($this->rootdir); - $error = ErrorHandler::stop(); - if (! $dh) { - throw new Exception\RuntimeException("can't read folders in maildir", 0, $error); - } - $dirs = []; - - while (($entry = readdir($dh)) !== false) { - // maildir++ defines folders must start with . - if ($entry[0] != '.' || $entry == '.' || $entry == '..') { - continue; - } - - if ($this->isMaildir($this->rootdir . $entry)) { - $dirs[] = $entry; - } - } - closedir($dh); - - sort($dirs); - $stack = [null]; - $folderStack = [null]; - $parentFolder = $this->rootFolder; - $parent = '.'; - - foreach ($dirs as $dir) { - do { - if (str_starts_with($dir, $parent)) { - $local = substr($dir, strlen((string) $parent)); - if (str_contains($local, $this->delim)) { - throw new Exception\RuntimeException('error while reading maildir'); - } - array_push($stack, $parent); - $parent = $dir . $this->delim; - $folder = new Storage\Folder($local, substr($dir, 1), true); - $parentFolder->$local = $folder; - array_push($folderStack, $parentFolder); - $parentFolder = $folder; - break; - } elseif ($stack) { - $parent = array_pop($stack); - $parentFolder = array_pop($folderStack); - } - } while ($stack); - if (! $stack) { - throw new Exception\RuntimeException('error while reading maildir'); - } - } - } - - /** - * get root folder or given folder - * - * @param string $rootFolder get folder structure for given folder, else root - * @throws InvalidArgumentException - * @return Folder root or wanted folder - */ - public function getFolders($rootFolder = null) - { - if (! $rootFolder || $rootFolder == 'INBOX') { - return $this->rootFolder; - } - - // rootdir is same as INBOX in maildir - if (str_starts_with($rootFolder, 'INBOX' . $this->delim)) { - $rootFolder = substr($rootFolder, 6); - } - $currentFolder = $this->rootFolder; - $subname = trim($rootFolder, $this->delim); - - while ($currentFolder) { - if (str_contains($subname, $this->delim)) { - [$entry, $subname] = explode($this->delim, $subname, 2); - } else { - $entry = $subname; - $subname = null; - } - - $currentFolder = $currentFolder->$entry; - - if (! $subname) { - break; - } - } - - if ($currentFolder->getGlobalName() != rtrim($rootFolder, $this->delim)) { - throw new Exception\InvalidArgumentException("folder $rootFolder not found"); - } - return $currentFolder; - } - - /** - * select given folder - * - * folder must be selectable! - * - * @param Storage\Folder|string $globalName global name of folder or - * instance for subfolder - * @throws Exception\RuntimeException - */ - public function selectFolder($globalName) - { - $this->currentFolder = (string) $globalName; - - // getting folder from folder tree for validation - $folder = $this->getFolders($this->currentFolder); - - try { - $this->openMaildir($this->rootdir . '.' . $folder->getGlobalName()); - } catch (Exception\ExceptionInterface $e) { - // check what went wrong - if (! $folder->isSelectable()) { - throw new Exception\RuntimeException("{$this->currentFolder} is not selectable", 0, $e); - } - // seems like file has vanished; rebuilding folder tree - but it's still an exception - $this->buildFolderTree(); - throw new Exception\RuntimeException( - 'seems like the maildir has vanished; I have rebuilt the folder tree; ' - . 'search for another folder and try again', - 0, - $e - ); - } - } - - /** - * get Storage\Folder instance for current folder - * - * @return string instance of current folder - */ - public function getCurrentFolder() - { - return $this->currentFolder; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Folder/Mbox.php b/lib/laminas/laminas-mail/src/Storage/Folder/Mbox.php deleted file mode 100644 index 3b6f540a0..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Folder/Mbox.php +++ /dev/null @@ -1,237 +0,0 @@ -rootdir = rtrim($dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - $folder = $params['folder'] ?? 'INBOX'; - - $this->buildFolderTree($this->rootdir); - $this->selectFolder((string) $folder); - $this->has['top'] = true; - $this->has['uniqueid'] = false; - } - - /** - * find all subfolders and mbox files for folder structure - * - * Result is save in Storage\Folder instances with the root in $this->rootFolder. - * $parentFolder and $parentGlobalName are only used internally for recursion. - * - * @param string $currentDir call with root dir, also used for recursion. - * @param Storage\Folder|null $parentFolder used for recursion - * @param string $parentGlobalName used for recursion - * @throws Exception\InvalidArgumentException - */ - protected function buildFolderTree($currentDir, $parentFolder = null, $parentGlobalName = '') - { - if (! $parentFolder) { - $this->rootFolder = new Storage\Folder('/', '/', false); - $parentFolder = $this->rootFolder; - } - - ErrorHandler::start(E_WARNING); - $dh = opendir($currentDir); - ErrorHandler::stop(); - if (! $dh) { - throw new Exception\InvalidArgumentException("can't read dir $currentDir"); - } - while (($entry = readdir($dh)) !== false) { - // ignore hidden files for mbox - if ($entry[0] == '.') { - continue; - } - $absoluteEntry = $currentDir . $entry; - $globalName = $parentGlobalName . DIRECTORY_SEPARATOR . $entry; - if (is_file($absoluteEntry) && $this->isMboxFile($absoluteEntry)) { - $parentFolder->$entry = new Storage\Folder($entry, $globalName); - continue; - } - if (! is_dir($absoluteEntry)) { /* || $entry == '.' || $entry == '..' */ - continue; - } - $folder = new Storage\Folder($entry, $globalName, false); - $parentFolder->$entry = $folder; - $this->buildFolderTree($absoluteEntry . DIRECTORY_SEPARATOR, $folder, $globalName); - } - - closedir($dh); - } - - /** - * get root folder or given folder - * - * @param string $rootFolder get folder structure for given folder, else root - * @return Storage\Folder root or wanted folder - * @throws Exception\InvalidArgumentException - */ - public function getFolders($rootFolder = null) - { - if (! $rootFolder) { - return $this->rootFolder; - } - - $currentFolder = $this->rootFolder; - $subname = trim($rootFolder, DIRECTORY_SEPARATOR); - while ($currentFolder) { - if (str_contains($subname, DIRECTORY_SEPARATOR)) { - [$entry, $subname] = explode(DIRECTORY_SEPARATOR, $subname, 2); - } else { - $entry = $subname; - $subname = null; - } - - $currentFolder = $currentFolder->$entry; - - if (! $subname) { - break; - } - } - - if ($currentFolder->getGlobalName() != DIRECTORY_SEPARATOR . trim($rootFolder, DIRECTORY_SEPARATOR)) { - throw new Exception\InvalidArgumentException("folder $rootFolder not found"); - } - return $currentFolder; - } - - /** - * select given folder - * - * folder must be selectable! - * - * @param Storage\Folder|string $globalName global name of folder or - * instance for subfolder - * @throws Exception\RuntimeException - */ - public function selectFolder($globalName) - { - $this->currentFolder = (string) $globalName; - - // getting folder from folder tree for validation - $folder = $this->getFolders($this->currentFolder); - - try { - $this->openMboxFile($this->rootdir . $folder->getGlobalName()); - } catch (Exception\ExceptionInterface $e) { - // check what went wrong - if (! $folder->isSelectable()) { - throw new Exception\RuntimeException("{$this->currentFolder} is not selectable", 0, $e); - } - // seems like file has vanished; rebuilding folder tree - but it's still an exception - $this->buildFolderTree($this->rootdir); - throw new Exception\RuntimeException( - 'seems like the mbox file has vanished; I have rebuilt the folder tree; ' - . 'search for another folder and try again', - 0, - $e - ); - } - } - - /** - * get Storage\Folder instance for current folder - * - * @return string instance of current folder - * @throws Exception\ExceptionInterface - */ - public function getCurrentFolder() - { - return $this->currentFolder; - } - - /** - * magic method for serialize() - * - * with this method you can cache the mbox class - * - * @return array name of variables - */ - public function __sleep() - { - return array_merge(parent::__sleep(), ['currentFolder', 'rootFolder', 'rootdir']); - } - - /** - * magic method for unserialize(), with this method you can cache the mbox class - */ - public function __wakeup() - { - // if cache is stall selectFolder() rebuilds the tree on error - parent::__wakeup(); - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Imap.php b/lib/laminas/laminas-mail/src/Storage/Imap.php deleted file mode 100644 index 25dc1b135..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Imap.php +++ /dev/null @@ -1,571 +0,0 @@ - Mail\Storage::FLAG_PASSED, - '\Answered' => Mail\Storage::FLAG_ANSWERED, - '\Seen' => Mail\Storage::FLAG_SEEN, - '\Unseen' => Mail\Storage::FLAG_UNSEEN, - '\Deleted' => Mail\Storage::FLAG_DELETED, - '\Draft' => Mail\Storage::FLAG_DRAFT, - '\Flagged' => Mail\Storage::FLAG_FLAGGED, - ]; - - /** - * IMAP flags to search criteria - * - * @var array - */ - protected static $searchFlags = [ - '\Recent' => 'RECENT', - '\Answered' => 'ANSWERED', - '\Seen' => 'SEEN', - '\Unseen' => 'UNSEEN', - '\Deleted' => 'DELETED', - '\Draft' => 'DRAFT', - '\Flagged' => 'FLAGGED', - ]; - - /** - * Count messages all messages in current box - * - * @param null $flags - * @throws Exception\RuntimeException - * @throws Protocol\Exception\RuntimeException - * @return int number of messages - */ - public function countMessages($flags = null) - { - if (! $this->currentFolder) { - throw new Exception\RuntimeException('No selected folder to count'); - } - - if ($flags === null) { - return count($this->protocol->search(['ALL'])); - } - - $params = []; - foreach ((array) $flags as $flag) { - if (isset(static::$searchFlags[$flag])) { - $params[] = static::$searchFlags[$flag]; - } else { - $params[] = 'KEYWORD'; - $params[] = $this->protocol->escapeString($flag); - } - } - return count($this->protocol->search($params)); - } - - /** - * get a list of messages with number and size - * - * @param int $id number of message - * @return int|array size of given message of list with all messages as [num => size] - * @throws Protocol\Exception\RuntimeException - */ - public function getSize($id = 0) - { - if ($id) { - return $this->protocol->fetch('RFC822.SIZE', $id); - } - return $this->protocol->fetch('RFC822.SIZE', 1, INF); - } - - /** - * Fetch a message - * - * @param int $id number of message - * @return Message - * @throws Protocol\Exception\RuntimeException - */ - public function getMessage($id) - { - $data = $this->protocol->fetch(['FLAGS', 'RFC822.HEADER'], $id); - $header = $data['RFC822.HEADER']; - - $flags = []; - foreach ($data['FLAGS'] as $flag) { - $flags[] = static::$knownFlags[$flag] ?? $flag; - } - - return new $this->messageClass(['handler' => $this, 'id' => $id, 'headers' => $header, 'flags' => $flags]); - } - - /** - * Get raw header of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message header - * @param int $topLines include this many lines with header (after an empty line) - * @return string raw header - * @throws Exception\RuntimeException - * @throws Protocol\Exception\RuntimeException - */ - public function getRawHeader($id, $part = null, $topLines = 0) - { - if ($part !== null) { - // TODO: implement - throw new Exception\RuntimeException('not implemented'); - } - - // TODO: toplines - return $this->protocol->fetch('RFC822.HEADER', $id); - } - - /** - * Get raw content of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message content - * @return string raw content - * @throws Protocol\Exception\RuntimeException - * @throws Exception\RuntimeException - */ - public function getRawContent($id, $part = null) - { - if ($part !== null) { - // TODO: implement - throw new Exception\RuntimeException('not implemented'); - } - - return $this->protocol->fetch('RFC822.TEXT', $id); - } - - /** - * create instance with parameters - * - * Supported parameters are - * - * - user username - * - host hostname or ip address of IMAP server [optional, default = 'localhost'] - * - password password for user 'username' [optional, default = ''] - * - port port for IMAP server [optional, default = 110] - * - ssl 'SSL' or 'TLS' for secure sockets - * - folder select this folder [optional, default = 'INBOX'] - * - * @param array|object|Protocol\Imap $params mail reader specific - * parameters or configured Imap protocol object - * @throws Exception\RuntimeException - * @throws Exception\InvalidArgumentException - * @throws Protocol\Exception\RuntimeException - */ - public function __construct($params) - { - $this->has['flags'] = true; - - if ($params instanceof Protocol\Imap) { - $this->protocol = $params; - try { - $this->selectFolder('INBOX'); - } catch (Exception\ExceptionInterface $e) { - throw new Exception\RuntimeException('cannot select INBOX, is this a valid transport?', 0, $e); - } - return; - } - - $params = ParamsNormalizer::normalizeParams($params); - - if (! isset($params['user'])) { - throw new Exception\InvalidArgumentException('need at least user in params'); - } - - $host = $params['host'] ?? 'localhost'; - $password = $params['password'] ?? ''; - $port = $params['port'] ?? null; - $ssl = $params['ssl'] ?? false; - $folder = $params['folder'] ?? 'INBOX'; - - if (null !== $port) { - $port = (int) $port; - } - - if (! is_string($ssl)) { - $ssl = (bool) $ssl; - } - - $this->protocol = new Protocol\Imap(); - - if (array_key_exists('novalidatecert', $params)) { - $this->protocol->setNoValidateCert((bool) $params['novalidatecert']); - } - - $this->protocol->connect((string) $host, $port, $ssl); - if (! $this->protocol->login((string) $params['user'], (string) $password)) { - throw new Exception\RuntimeException('cannot login, user or password wrong'); - } - $this->selectFolder((string) $folder); - } - - /** - * Close resource for mail lib. - * - * If you need to control, when the resource is closed. Otherwise the - * destructor would call this. - */ - public function close() - { - $this->currentFolder = ''; - $this->protocol->logout(); - } - - /** - * Keep the server busy. - * - * @throws Exception\RuntimeException - */ - public function noop() - { - if (! $this->protocol->noop()) { - throw new Exception\RuntimeException('could not do nothing'); - } - } - - /** - * Remove a message from server. - * - * If you're doing that from a web environment you should be careful and - * use a uniqueid as parameter if possible to identify the message. - * - * @param int $id number of message - * @throws Exception\RuntimeException - */ - public function removeMessage($id) - { - if (! $this->protocol->store([Mail\Storage::FLAG_DELETED], $id, null, '+')) { - throw new Exception\RuntimeException('cannot set deleted flag'); - } - // TODO: expunge here or at close? we can handle an error here better and are more fail safe - if (! $this->protocol->expunge()) { - throw new Exception\RuntimeException('message marked as deleted, but could not expunge'); - } - } - - /** - * get unique id for one or all messages - * - * if storage does not support unique ids it's the same as the message - * number. - * - * @param int|null $id message number - * @return array|string message number for given message or all messages as array - * @throws Protocol\Exception\RuntimeException - */ - public function getUniqueId($id = null) - { - if ($id) { - return $this->protocol->fetch('UID', $id); - } - - return $this->protocol->fetch('UID', 1, INF); - } - - /** - * get a message number from a unique id - * - * I.e. if you have a webmailer that supports deleting messages you should - * use unique ids as parameter and use this method to translate it to - * message number right before calling removeMessage() - * - * @param string $id unique id - * @throws Exception\InvalidArgumentException - * @return int message number - */ - public function getNumberByUniqueId($id) - { - // TODO: use search to find number directly - $ids = $this->getUniqueId(); - foreach ($ids as $k => $v) { - if ($v == $id) { - return $k; - } - } - - throw new Exception\InvalidArgumentException('unique id not found'); - } - - /** - * get root folder or given folder - * - * @param string $rootFolder get folder structure for given folder, else root - * @throws Exception\RuntimeException - * @throws Exception\InvalidArgumentException - * @throws Protocol\Exception\RuntimeException - * @return Folder root or wanted folder - */ - public function getFolders($rootFolder = null) - { - $folders = $this->protocol->listMailbox((string) $rootFolder); - if (! $folders) { - throw new Exception\InvalidArgumentException('folder not found'); - } - - ksort($folders, SORT_STRING); - $root = new Folder('/', '/', false); - $stack = [null]; - $folderStack = [null]; - $parentFolder = $root; - $parent = ''; - - foreach ($folders as $globalName => $data) { - do { - if (! $parent || str_starts_with($globalName, ! is_string($parent) ? (string) $parent : $parent)) { - $pos = strrpos($globalName, (string) $data['delim']); - if ($pos === false) { - $localName = $globalName; - } else { - $localName = substr($globalName, $pos + 1); - } - $selectable = ! $data['flags'] || ! in_array('\\Noselect', $data['flags']); - - array_push($stack, $parent); - $parent = $globalName . $data['delim']; - $folder = new Folder($localName, $globalName, $selectable); - $parentFolder->$localName = $folder; - array_push($folderStack, $parentFolder); - $parentFolder = $folder; - $this->delimiter = $data['delim']; - break; - } elseif ($stack) { - $parent = array_pop($stack); - $parentFolder = array_pop($folderStack); - } - } while ($stack); - if (! $stack) { - throw new Exception\RuntimeException('error while constructing folder tree'); - } - } - - return $root; - } - - /** - * select given folder - * - * folder must be selectable! - * - * @param Folder|string $globalName global name of folder or instance for subfolder - * @throws Exception\RuntimeException - * @throws Protocol\Exception\RuntimeException - */ - public function selectFolder($globalName) - { - $this->currentFolder = (string) $globalName; - if (! $this->protocol->select($this->currentFolder)) { - $this->currentFolder = ''; - throw new Exception\RuntimeException('cannot change folder, maybe it does not exist'); - } - } - - /** - * get Folder instance for current folder - * - * @return string instance of current folder - */ - public function getCurrentFolder() - { - return $this->currentFolder; - } - - /** - * create a new folder - * - * This method also creates parent folders if necessary. Some mail storages - * may restrict, which folder may be used as parent or which chars may be - * used in the folder name - * - * @param string $name global name of folder, local name if $parentFolder - * is set - * @param string|Folder $parentFolder parent folder for new folder, else - * root folder is parent - * @throws Exception\RuntimeException - */ - public function createFolder($name, $parentFolder = null) - { - // TODO: we assume / as the hierarchy delim - need to get that from the folder class! - if ($parentFolder instanceof Folder) { - $folder = $parentFolder->getGlobalName() . '/' . $name; - } elseif ($parentFolder !== null) { - $folder = $parentFolder . '/' . $name; - } else { - $folder = $name; - } - - if (! $this->protocol->create($folder)) { - throw new Exception\RuntimeException('cannot create folder'); - } - } - - /** - * remove a folder - * - * @param string|Folder $name name or instance of folder - * @throws Exception\RuntimeException - */ - public function removeFolder($name) - { - if ($name instanceof Folder) { - $name = $name->getGlobalName(); - } - - if (! $this->protocol->delete($name)) { - throw new Exception\RuntimeException('cannot delete folder'); - } - } - - /** - * rename and/or move folder - * - * The new name has the same restrictions as in createFolder() - * - * @param string|Folder $oldName name or instance of folder - * @param string $newName new global name of folder - * @throws Exception\RuntimeException - */ - public function renameFolder($oldName, $newName) - { - if ($oldName instanceof Folder) { - $oldName = $oldName->getGlobalName(); - } - - if (! $this->protocol->rename($oldName, $newName)) { - throw new Exception\RuntimeException('cannot rename folder'); - } - } - - /** - * append a new message to mail storage - * - * @param string $message message as string or instance of message class - * @param null|string|Folder $folder folder for new message, else current - * folder is taken - * @param null|array $flags set flags for new message, else a default set - * is used - * @throws Exception\RuntimeException - */ - public function appendMessage($message, $folder = null, $flags = null) - { - if ($folder === null) { - $folder = $this->currentFolder; - } - - if ($flags === null) { - $flags = [Mail\Storage::FLAG_SEEN]; - } - - // TODO: handle class instances for $message - if (! $this->protocol->append($folder, $message, $flags)) { - throw new Exception\RuntimeException( - 'cannot create message, please check if the folder exists and your flags' - ); - } - } - - /** - * copy an existing message - * - * @param int $id number of message - * @param string|Folder $folder name or instance of target folder - * @throws Exception\RuntimeException - */ - public function copyMessage($id, $folder) - { - if (! $this->protocol->copy($folder, $id)) { - throw new Exception\RuntimeException('cannot copy message, does the folder exist?'); - } - } - - /** - * move an existing message - * - * NOTE: IMAP has no native move command, thus it's emulated with copy and delete - * - * @param int $id number of message - * @param string|Folder $folder name or instance of target folder - * @throws Exception\RuntimeException - */ - public function moveMessage($id, $folder) - { - $this->copyMessage($id, $folder); - $this->removeMessage($id); - } - - /** - * set flags for message - * - * NOTE: this method can't set the recent flag. - * - * @param int $id number of message - * @param array $flags new flags for message - * @throws Exception\RuntimeException - */ - public function setFlags($id, $flags) - { - if (! $this->protocol->store($flags, $id)) { - throw new Exception\RuntimeException( - 'cannot set flags, have you tried to set the recent flag or special chars?' - ); - } - } - - /** - * get IMAP delimiter - * - * @return string|null - */ - public function delimiter() - { - if (! isset($this->delimiter)) { - $this->getFolders(); - } - return $this->delimiter; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Maildir.php b/lib/laminas/laminas-mail/src/Storage/Maildir.php deleted file mode 100644 index 4936d6999..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Maildir.php +++ /dev/null @@ -1,460 +0,0 @@ - - */ - protected $messageClass = File::class; - - /** - * data of found message files in maildir dir - * - * @var array - */ - protected $files = []; - - /** - * known flag chars in filenames - * - * This list has to be in alphabetical order for setFlags() - * - * @var array - */ - protected static $knownFlags = [ - 'D' => Mail\Storage::FLAG_DRAFT, - 'F' => Mail\Storage::FLAG_FLAGGED, - 'P' => Mail\Storage::FLAG_PASSED, - 'R' => Mail\Storage::FLAG_ANSWERED, - 'S' => Mail\Storage::FLAG_SEEN, - 'T' => Mail\Storage::FLAG_DELETED, - ]; - - // TODO: getFlags($id) for fast access if headers are not needed (i.e. just setting flags)? - - /** - * Count messages all messages in current box - * - * @param mixed $flags - * @return int number of messages - */ - public function countMessages($flags = null) - { - if ($flags === null) { - return count($this->files); - } - - $count = 0; - if (! is_array($flags)) { - foreach ($this->files as $file) { - if (isset($file['flaglookup'][$flags])) { - ++$count; - } - } - return $count; - } - - $flags = array_flip($flags); - foreach ($this->files as $file) { - foreach ($flags as $flag => $v) { - if (! isset($file['flaglookup'][$flag])) { - continue 2; - } - } - ++$count; - } - return $count; - } - - /** - * Get one or all fields from file structure. Also checks if message is valid - * - * @param int $id message number - * @param string|null $field wanted field - * @throws Exception\InvalidArgumentException - * @return string|array wanted field or all fields as array - */ - protected function getFileData($id, $field = null) - { - if (! isset($this->files[$id - 1])) { - throw new Exception\InvalidArgumentException('id does not exist'); - } - - if (! $field) { - return $this->files[$id - 1]; - } - - if (! isset($this->files[$id - 1][$field])) { - throw new Exception\InvalidArgumentException('field does not exist'); - } - - return $this->files[$id - 1][$field]; - } - - /** - * Get a list of messages with number and size - * - * @param int|null $id number of message or null for all messages - * @return int|array size of given message of list with all messages as array(num => size) - */ - public function getSize($id = null) - { - if ($id !== null) { - $filedata = $this->getFileData($id); - return $filedata['size'] ?? filesize($filedata['filename']); - } - - $result = []; - foreach ($this->files as $num => $data) { - $result[$num + 1] = $data['size'] ?? filesize($data['filename']); - } - - return $result; - } - - /** - * Fetch a message - * - * @param int $id number of message - * @return File - * @throws ExceptionInterface - */ - public function getMessage($id) - { - // TODO that's ugly, would be better to let the message class decide - if ( - trim($this->messageClass, '\\') === File::class - || is_subclass_of($this->messageClass, File::class) - ) { - return new $this->messageClass([ - 'file' => $this->getFileData($id, 'filename'), - 'flags' => $this->getFileData($id, 'flags'), - ]); - } - - return new $this->messageClass([ - 'handler' => $this, - 'id' => $id, - 'headers' => $this->getRawHeader($id), - 'flags' => $this->getFileData($id, 'flags'), - ]); - } - - /** - * Get raw header of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message header - * @param int $topLines include this many lines with header (after an empty line) - * @throws Exception\RuntimeException - * @return string raw header - */ - public function getRawHeader($id, $part = null, $topLines = 0) - { - if ($part !== null) { - // TODO: implement - throw new Exception\RuntimeException('not implemented'); - } - - $fh = fopen($this->getFileData($id, 'filename'), 'r'); - - $content = ''; - while (! feof($fh)) { - $line = fgets($fh); - if (! trim($line)) { - break; - } - $content .= $line; - } - - fclose($fh); - return $content; - } - - /** - * Get raw content of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message content - * @throws Exception\RuntimeException - * @return string raw content - */ - public function getRawContent($id, $part = null) - { - if ($part !== null) { - // TODO: implement - throw new Exception\RuntimeException('not implemented'); - } - - $fh = fopen($this->getFileData($id, 'filename'), 'r'); - - while (! feof($fh)) { - $line = fgets($fh); - if (! trim($line)) { - break; - } - } - - $content = stream_get_contents($fh); - fclose($fh); - return $content; - } - - /** - * Create instance with parameters - * Supported parameters are: - * - dirname dirname of mbox file - * - * @param array|object $params Array, iterable object, or stdClass object - * with reader specific parameters - * @throws Exception\InvalidArgumentException - */ - public function __construct($params) - { - $params = ParamsNormalizer::normalizeParams($params); - - if (! isset($params['dirname'])) { - throw new Exception\InvalidArgumentException('no dirname provided in params'); - } - - $dirname = (string) $params['dirname']; - - if (! is_dir($dirname)) { - throw new Exception\InvalidArgumentException(sprintf('Maildir "%s" is not a directory', $dirname)); - } - - if (! $this->isMaildir($dirname)) { - throw new Exception\InvalidArgumentException('invalid maildir given'); - } - - $this->has['top'] = true; - $this->has['flags'] = true; - $this->openMaildir($dirname); - } - - /** - * check if a given dir is a valid maildir - * - * @param string $dirname name of dir - * @return bool dir is valid maildir - */ - protected function isMaildir($dirname) - { - if (file_exists($dirname . '/new') && ! is_dir($dirname . '/new')) { - return false; - } - if (file_exists($dirname . '/tmp') && ! is_dir($dirname . '/tmp')) { - return false; - } - return is_dir($dirname . '/cur'); - } - - /** - * open given dir as current maildir - * - * @param string $dirname name of maildir - * @throws Exception\RuntimeException - */ - protected function openMaildir($dirname) - { - if ($this->files) { - $this->close(); - } - - ErrorHandler::start(E_WARNING); - $dh = opendir($dirname . '/cur/'); - $error = ErrorHandler::stop(); - if (! $dh) { - throw new Exception\RuntimeException('cannot open maildir', 0, $error); - } - $this->getMaildirFiles($dh, $dirname . '/cur/'); - closedir($dh); - - ErrorHandler::start(E_WARNING); - $dh = opendir($dirname . '/new/'); - $error = ErrorHandler::stop(); - if (! $dh) { - throw new Exception\RuntimeException('cannot read recent mails in maildir', 0, $error); - } - - $this->getMaildirFiles($dh, $dirname . '/new/', [Mail\Storage::FLAG_RECENT]); - closedir($dh); - } - - /** - * find all files in opened dir handle and add to maildir files - * - * @param resource $dh dir handle used for search - * @param string $dirname dirname of dir in $dh - * @param array $defaultFlags default flags for given dir - */ - protected function getMaildirFiles($dh, $dirname, $defaultFlags = []) - { - while (($entry = readdir($dh)) !== false) { - if ($entry[0] == '.' || ! is_file($dirname . $entry)) { - continue; - } - - if (str_contains($entry, ':')) { - [$uniq, $info] = explode(':', $entry, 2); - } else { - $uniq = $entry; - $info = ''; - } - - if (str_contains($uniq, ',')) { - [, $size] = explode(',', $uniq, 2); - } else { - $size = ''; - } - - if (strlen($size) >= 2 && $size[0] === 'S' && $size[1] === '=') { - $size = substr($size, 2); - } - - if (! ctype_digit($size)) { - $size = null; - } - - if (str_contains($info, ',')) { - [$version, $flags] = explode(',', $info, 2); - } else { - $version = $info; - $flags = ''; - } - - if ($version !== '2') { - $flags = ''; - } - - $namedFlags = $defaultFlags; - $length = strlen($flags); - for ($i = 0; $i < $length; ++$i) { - $flag = $flags[$i]; - $namedFlags[$flag] = static::$knownFlags[$flag] ?? $flag; - } - - $data = [ - 'uniq' => $uniq, - 'flags' => $namedFlags, - 'flaglookup' => array_flip($namedFlags), - 'filename' => $dirname . $entry, - ]; - if ($size !== null) { - $data['size'] = (int) $size; - } - $this->files[] = $data; - } - - usort($this->files, static fn($a, $b): int => strcmp($a['filename'], $b['filename'])); - } - - /** - * Close resource for mail lib. If you need to control, when the resource - * is closed. Otherwise the destructor would call this. - */ - public function close() - { - $this->files = []; - } - - /** - * Waste some CPU cycles doing nothing. - * - * @return bool always return true - */ - public function noop() - { - return true; - } - - /** - * stub for not supported message deletion - * - * @param int $id - * @throws Exception\RuntimeException - */ - public function removeMessage($id) - { - throw new Exception\RuntimeException('maildir is (currently) read-only'); - } - - /** - * get unique id for one or all messages - * - * if storage does not support unique ids it's the same as the message number - * - * @param int|null $id message number - * @return array|string message number for given message or all messages as array - */ - public function getUniqueId($id = null) - { - if ($id) { - return $this->getFileData($id, 'uniq'); - } - - $ids = []; - foreach ($this->files as $num => $file) { - $ids[$num + 1] = $file['uniq']; - } - return $ids; - } - - /** - * get a message number from a unique id - * - * I.e. if you have a webmailer that supports deleting messages you should use unique ids - * as parameter and use this method to translate it to message number right before calling removeMessage() - * - * @param string $id unique id - * @throws Exception\InvalidArgumentException - * @return int message number - */ - public function getNumberByUniqueId($id) - { - foreach ($this->files as $num => $file) { - if ($file['uniq'] == $id) { - return $num + 1; - } - } - - throw new Exception\InvalidArgumentException('unique id not found'); - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Mbox.php b/lib/laminas/laminas-mail/src/Storage/Mbox.php deleted file mode 100644 index b4db7bd11..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Mbox.php +++ /dev/null @@ -1,440 +0,0 @@ - start, 'separator' => headersep, 'end' => end) - * - * @var array - */ - protected $positions; - - /** - * used message class, change it in an extended class to extend the returned message class - * - * @var class-string - */ - protected $messageClass = File::class; - - /** - * end of Line for messages - * - * @var string|null - */ - // phpcs:ignore WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCapsProperty - protected $messageEOL; - - /** - * Count messages all messages in current box - * - * @return int number of messages - * @throws ExceptionInterface - */ - public function countMessages() - { - return count($this->positions); - } - - /** - * Get a list of messages with number and size - * - * @param int|null $id number of message or null for all messages - * @return int|array size of given message of list with all messages as array(num => size) - */ - public function getSize($id = 0) - { - if ($id) { - $pos = $this->positions[$id - 1]; - return $pos['end'] - $pos['start']; - } - - $result = []; - foreach ($this->positions as $num => $pos) { - $result[$num + 1] = $pos['end'] - $pos['start']; - } - - return $result; - } - - /** - * Get positions for mail message or throw exception if id is invalid - * - * @param int $id number of message - * @throws Exception\InvalidArgumentException - * @return array positions as in positions - */ - protected function getPos($id) - { - if (! isset($this->positions[$id - 1])) { - throw new Exception\InvalidArgumentException('id does not exist'); - } - - return $this->positions[$id - 1]; - } - - /** - * Fetch a message - * - * @param int $id number of message - * @return File - * @throws ExceptionInterface - */ - public function getMessage($id) - { - // TODO that's ugly, would be better to let the message class decide - if ( - is_subclass_of($this->messageClass, File::class) - || strtolower($this->messageClass) === strtolower(File::class) - ) { - // TODO top/body lines - $messagePos = $this->getPos($id); - - $messageClassParams = [ - 'file' => $this->fh, - 'startPos' => $messagePos['start'], - 'endPos' => $messagePos['end'], - ]; - - if (isset($this->messageEOL)) { - $messageClassParams['EOL'] = $this->messageEOL; - } - - return new $this->messageClass($messageClassParams); - } - - /** @todo Uncomment once we know how to count body lines */ - // $bodyLines = 0; - - $message = $this->getRawHeader($id); - - /* Once we know how to count body lines, we should uncomment the - * following, which would append the body content to the headers. - * - if ($bodyLines) { - $message .= "\n"; - while ($bodyLines-- && ftell($this->fh) < $this->positions[$id - 1]['end']) { - $message .= fgets($this->fh); - } - } - */ - - return new $this->messageClass(['handler' => $this, 'id' => $id, 'headers' => $message]); - } - - /** - * Get raw header of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message header - * @param int $topLines include this many lines with header (after an empty line) - * @return string raw header - * @throws \Laminas\Mail\Protocol\Exception\ExceptionInterface - * @throws ExceptionInterface - */ - public function getRawHeader($id, $part = null, $topLines = 0) - { - if ($part !== null) { - // TODO: implement - throw new Exception\RuntimeException('not implemented'); - } - $messagePos = $this->getPos($id); - // TODO: toplines - return stream_get_contents($this->fh, $messagePos['separator'] - $messagePos['start'], $messagePos['start']); - } - - /** - * Get raw content of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message content - * @return string raw content - * @throws \Laminas\Mail\Protocol\Exception\ExceptionInterface - * @throws ExceptionInterface - */ - public function getRawContent($id, $part = null) - { - if ($part !== null) { - // TODO: implement - throw new Exception\RuntimeException('not implemented'); - } - $messagePos = $this->getPos($id); - return stream_get_contents($this->fh, $messagePos['end'] - $messagePos['separator'], $messagePos['separator']); - } - - /** - * Create instance with parameters - * Supported parameters are: - * - filename filename of mbox file - * - * @param array|object|Config $params mail reader specific parameters - * @throws Exception\InvalidArgumentException - */ - public function __construct($params) - { - $params = ParamsNormalizer::normalizeParams($params); - - if (! isset($params['filename'])) { - throw new Exception\InvalidArgumentException('no valid filename given in params'); - } - - if (isset($params['messageEOL'])) { - $this->messageEOL = (string) $params['messageEOL']; - } - - $this->openMboxFile((string) $params['filename']); - $this->has['top'] = true; - $this->has['uniqueid'] = false; - } - - /** - * check if given file is a mbox file - * - * if $file is a resource its file pointer is moved after the first line - * - * @param resource|string $file stream resource of name of file - * @param bool $fileIsString file is string or resource - * @return bool file is mbox file - */ - protected function isMboxFile($file, $fileIsString = true) - { - if ($fileIsString) { - ErrorHandler::start(E_WARNING); - $file = fopen($file, 'r'); - ErrorHandler::stop(); - if (! $file) { - return false; - } - } else { - fseek($file, 0); - } - - $result = false; - - $line = fgets($file) ?: ''; - if (str_starts_with($line, 'From ')) { - $result = true; - } - - if ($fileIsString) { - ErrorHandler::start(E_WARNING); - fclose($file); - ErrorHandler::stop(); - } - - return $result; - } - - /** - * open given file as current mbox file - * - * @param string $filename filename of mbox file - * @throws Exception\RuntimeException - * @throws Exception\InvalidArgumentException - */ - protected function openMboxFile($filename) - { - if ($this->fh) { - $this->close(); - } - - if (is_dir($filename)) { - throw new Exception\InvalidArgumentException('file is not a valid mbox file'); - } - - ErrorHandler::start(); - $this->fh = fopen($filename, 'r'); - $error = ErrorHandler::stop(); - if (! $this->fh) { - throw new Exception\RuntimeException('cannot open mbox file', 0, $error); - } - $this->filename = $filename; - $this->filemtime = filemtime($this->filename); - - if (! $this->isMboxFile($this->fh, false)) { - ErrorHandler::start(E_WARNING); - fclose($this->fh); - $error = ErrorHandler::stop(); - throw new Exception\InvalidArgumentException('file is not a valid mbox format', 0, $error); - } - - $messagePos = ['start' => ftell($this->fh), 'separator' => 0, 'end' => 0]; - while (($line = fgets($this->fh)) !== false) { - if (str_starts_with($line, 'From ')) { - $messagePos['end'] = ftell($this->fh) - strlen($line) - 2; // + newline - if (! $messagePos['separator']) { - $messagePos['separator'] = $messagePos['end']; - } - $this->positions[] = $messagePos; - $messagePos = ['start' => ftell($this->fh), 'separator' => 0, 'end' => 0]; - } - if (! $messagePos['separator'] && ! trim($line)) { - $messagePos['separator'] = ftell($this->fh); - } - } - - $messagePos['end'] = ftell($this->fh); - if (! $messagePos['separator']) { - $messagePos['separator'] = $messagePos['end']; - } - $this->positions[] = $messagePos; - } - - /** - * Close resource for mail lib. If you need to control, when the resource - * is closed. Otherwise the destructor would call this. - */ - public function close() - { - if (is_resource($this->fh)) { - fclose($this->fh); - } - $this->positions = []; - } - - /** - * Waste some CPU cycles doing nothing. - * - * @return bool always return true - */ - public function noop() - { - return true; - } - - /** - * stub for not supported message deletion - * - * @param int $id message number - * @throws Exception\RuntimeException - */ - public function removeMessage($id) - { - throw new Exception\RuntimeException('mbox is read-only'); - } - - /** - * get unique id for one or all messages - * - * Mbox does not support unique ids (yet) - it's always the same as the message number. - * That shouldn't be a problem, because we can't change mbox files. Therefor the message - * number is save enough. - * - * @param int|null $id message number - * @return array|string message number for given message or all messages as array - * @throws ExceptionInterface - */ - public function getUniqueId($id = null) - { - if ($id) { - // check if id exists - $this->getPos($id); - return $id; - } - - $range = range(1, $this->countMessages()); - return array_combine($range, $range); - } - - /** - * get a message number from a unique id - * - * I.e. if you have a webmailer that supports deleting messages you should use unique ids - * as parameter and use this method to translate it to message number right before calling removeMessage() - * - * @param string $id unique id - * @return int message number - * @throws ExceptionInterface - */ - public function getNumberByUniqueId($id) - { - // check if id exists - $this->getPos($id); - return $id; - } - - /** - * magic method for serialize() - * - * with this method you can cache the mbox class - * - * @return array name of variables - */ - public function __sleep() - { - return ['filename', 'positions', 'filemtime']; - } - - /** - * magic method for unserialize() - * - * with this method you can cache the mbox class - * for cache validation the mtime of the mbox file is used - * - * @throws Exception\RuntimeException - */ - public function __wakeup() - { - ErrorHandler::start(); - $filemtime = filemtime($this->filename); - ErrorHandler::stop(); - if ($this->filemtime != $filemtime) { - $this->close(); - $this->openMboxFile($this->filename); - } else { - ErrorHandler::start(); - $this->fh = fopen($this->filename, 'r'); - $error = ErrorHandler::stop(); - if (! $this->fh) { - throw new Exception\RuntimeException('cannot open mbox file', 0, $error); - } - } - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Message.php b/lib/laminas/laminas-mail/src/Storage/Message.php deleted file mode 100644 index 9cad04c84..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Message.php +++ /dev/null @@ -1,87 +0,0 @@ -flags = array_combine($params['flags'], $params['flags']); - } - - parent::__construct($params); - } - - /** - * return toplines as found after headers - * - * @return string toplines - */ - public function getTopLines() - { - return $this->topLines; - } - - /** - * check if flag is set - * - * @param mixed $flag a flag name, use constants defined in \Laminas\Mail\Storage - * @return bool true if set, otherwise false - */ - public function hasFlag($flag) - { - return isset($this->flags[$flag]); - } - - /** - * get all set flags - * - * @return array array with flags, key and value are the same for easy lookup - */ - public function getFlags() - { - return $this->flags; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Message/File.php b/lib/laminas/laminas-mail/src/Storage/Message/File.php deleted file mode 100644 index 72a0ebe2f..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Message/File.php +++ /dev/null @@ -1,68 +0,0 @@ -flags = array_combine($params['flags'], $params['flags']); - } - - parent::__construct($params); - } - - /** - * return toplines as found after headers - * - * @return string toplines - */ - public function getTopLines() - { - return $this->topLines; - } - - /** - * check if flag is set - * - * @param mixed $flag a flag name, use constants defined in \Laminas\Mail\Storage - * @return bool true if set, otherwise false - */ - public function hasFlag($flag) - { - return isset($this->flags[$flag]); - } - - /** - * get all set flags - * - * @return array array with flags, key and value are the same for easy lookup - */ - public function getFlags() - { - return $this->flags; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Message/MessageInterface.php b/lib/laminas/laminas-mail/src/Storage/Message/MessageInterface.php deleted file mode 100644 index 15d82273c..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Message/MessageInterface.php +++ /dev/null @@ -1,28 +0,0 @@ - - */ - public static function normalizeParams(mixed $params): array - { - if ($params instanceof Traversable) { - $params = iterator_to_array($params); - } - - if (is_object($params)) { - $params = get_object_vars($params); - } - - if (! is_array($params)) { - throw new Exception\InvalidArgumentException(sprintf( - 'Invalid $params provided; expected array|Traversable|object, received %s', - gettype($params) - )); - } - - Assert::isMap($params, 'Expected $params to have only string keys'); - return $params; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Part.php b/lib/laminas/laminas-mail/src/Storage/Part.php deleted file mode 100644 index 26b761c08..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Part.php +++ /dev/null @@ -1,496 +0,0 @@ - value) or string, if a content part is found it's used as toplines - * - noToplines ignore content found after headers in param 'headers' - * - content content as string - * - strict strictly parse raw content - * - * @param array $params full message with or without headers - * @throws Exception\InvalidArgumentException - */ - public function __construct(array $params) - { - if (isset($params['handler'])) { - if (! $params['handler'] instanceof AbstractStorage) { - throw new Exception\InvalidArgumentException('handler is not a valid mail handler'); - } - if (! isset($params['id'])) { - throw new Exception\InvalidArgumentException('need a message id with a handler'); - } - - $this->mail = $params['handler']; - $this->messageNum = $params['id']; - } - - $params['strict'] ??= false; - - if (isset($params['raw'])) { - Mime\Decode::splitMessage( - $params['raw'], - $this->headers, - $this->content, - Mime\Mime::LINEEND, - $params['strict'] - ); - } elseif (isset($params['headers'])) { - if (is_array($params['headers'])) { - $this->headers = new Headers(); - $this->headers->addHeaders($params['headers']); - } else { - if (empty($params['noToplines'])) { - Mime\Decode::splitMessage($params['headers'], $this->headers, $this->topLines); - } else { - $this->headers = Headers::fromString($params['headers']); - } - } - - if (isset($params['content'])) { - $this->content = $params['content']; - } - } - } - - /** - * Check if part is a multipart message - * - * @return bool if part is multipart - */ - public function isMultipart() - { - try { - return stripos($this->contentType, 'multipart/') === 0; - } catch (Exception\ExceptionInterface) { - return false; - } - } - - /** - * Body of part - * - * If part is multipart the raw content of this part with all sub parts is returned - * - * @throws Exception\RuntimeException - * @return string body - */ - public function getContent() - { - if ($this->content !== null) { - return $this->content; - } - - if ($this->mail) { - return $this->mail->getRawContent($this->messageNum); - } - - throw new Exception\RuntimeException('no content'); - } - - /** - * Return size of part - * - * Quite simple implemented currently (not decoding). Handle with care. - * - * @return int size - */ - public function getSize() - { - return strlen($this->getContent()); - } - - /** - * Cache content and split in parts if multipart - * - * @throws Exception\RuntimeException - * @return null - */ - protected function cacheContent() - { - // caching content if we can't fetch parts - if ($this->content === null && $this->mail) { - $this->content = $this->mail->getRawContent($this->messageNum); - } - - if (! $this->isMultipart()) { - return; - } - - // split content in parts - $boundary = $this->getHeaderField('content-type', 'boundary'); - if (! $boundary) { - throw new Exception\RuntimeException('no boundary found in content type to split message'); - } - $parts = Mime\Decode::splitMessageStruct($this->content, $boundary); - if ($parts === null) { - return; - } - $counter = 1; - foreach ($parts as $part) { - $this->parts[$counter++] = new static(['headers' => $part['header'], 'content' => $part['body']]); - } - } - - /** - * Get part of multipart message - * - * @param int $num number of part starting with 1 for first part - * @throws Exception\RuntimeException - * @return Part wanted part - */ - public function getPart($num) - { - if (isset($this->parts[$num])) { - return $this->parts[$num]; - } - - if (! $this->mail && $this->content === null) { - throw new Exception\RuntimeException('part not found'); - } - - // if ($this->mail && $this->mail->hasFetchPart) { - // TODO: fetch part - // return - // } - - $this->cacheContent(); - - if (! isset($this->parts[$num])) { - throw new Exception\RuntimeException('part not found'); - } - - return $this->parts[$num]; - } - - /** - * Count parts of a multipart part - * - * @return int number of sub-parts - */ - public function countParts() - { - if ($this->countParts) { - return $this->countParts; - } - - $this->countParts = count($this->parts); - if ($this->countParts) { - return $this->countParts; - } - - // if ($this->mail && $this->mail->hasFetchPart) { - // TODO: fetch part - // return - // } - - $this->cacheContent(); - - $this->countParts = count($this->parts); - return $this->countParts; - } - - /** - * Access headers collection - * - * Lazy-loads if not already attached. - * - * @return Headers - * @throws Exception\RuntimeException - */ - public function getHeaders() - { - if (null === $this->headers) { - if ($this->mail) { - $part = $this->mail->getRawHeader($this->messageNum); - $this->headers = Headers::fromString($part); - } else { - $this->headers = new Headers(); - } - } - if (! $this->headers instanceof Headers) { - throw new Exception\RuntimeException( - '$this->headers must be an instance of Headers' - ); - } - - return $this->headers; - } - - /** - * Get a header in specified format - * - * Internally headers that occur more than once are saved as array, all other as string. If $format - * is set to string implode is used to concat the values (with Mime::LINEEND as delim). - * - * @param string $name name of header, matches case-insensitive, but camel-case is replaced with dashes - * @param string $format change type of return value to 'string' or 'array' - * @throws Exception\InvalidArgumentException - * @return string|array|HeaderInterface|ArrayIterator value of header in wanted or internal format - */ - public function getHeader($name, $format = null) - { - $header = $this->getHeaders()->get($name); - if ($header === false) { - $lowerName = strtolower(preg_replace('%([a-z])([A-Z])%', '\1-\2', $name)); - $header = $this->getHeaders()->get($lowerName); - if ($header === false) { - throw new Exception\InvalidArgumentException( - "Header with Name $name or $lowerName not found" - ); - } - } - - switch ($format) { - case 'string': - if ($header instanceof HeaderInterface) { - $return = $header->getFieldValue(HeaderInterface::FORMAT_RAW); - } else { - $return = trim(implode( - Mime\Mime::LINEEND, - array_map(static fn($header): string - => $header->getFieldValue(HeaderInterface::FORMAT_RAW), iterator_to_array($header)) - ), Mime\Mime::LINEEND); - } - break; - case 'array': - if ($header instanceof HeaderInterface) { - $return = [$header->getFieldValue()]; - } else { - $return = []; - foreach ($header as $h) { - $return[] = $h->getFieldValue(HeaderInterface::FORMAT_RAW); - } - } - break; - default: - $return = $header; - } - - return $return; - } - - /** - * Get a specific field from a header like content type or all fields as array - * - * If the header occurs more than once, only the value from the first header - * is returned. - * - * Throws an Exception if the requested header does not exist. If - * the specific header field does not exist, returns null. - * - * @param string $name name of header, like in getHeader() - * @param string $wantedPart the wanted part, default is first, if null an array with all parts is returned - * @param string $firstName key name for the first part - * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value) - * @throws RuntimeException - */ - public function getHeaderField($name, $wantedPart = '0', $firstName = '0') - { - return Mime\Decode::splitHeaderField(current($this->getHeader($name, 'array')), $wantedPart, $firstName); - } - - /** - * Getter for mail headers - name is matched in lowercase - * - * This getter is short for Part::getHeader($name, 'string') - * - * @see Part::getHeader() - * - * @param string $name header name - * @return string value of header - * @throws Exception\ExceptionInterface - */ - public function __get($name) - { - return $this->getHeader($name, 'string'); - } - - /** - * Isset magic method proxy to hasHeader - * - * This method is short syntax for Part::hasHeader($name); - * - * @see Part::hasHeader - * - * @param string $name - * @return bool - */ - public function __isset($name) - { - return $this->getHeaders()->has($name); - } - - /** - * magic method to get content of part - * - * @return string content - */ - public function __toString(): string - { - return $this->getContent(); - } - - /** - * implements RecursiveIterator::hasChildren() - * - * @return bool current element has children/is multipart - */ - #[ReturnTypeWillChange] - public function hasChildren() - { - $current = $this->current(); - return $current && $current instanceof self && $current->isMultipart(); - } - - /** - * implements RecursiveIterator::getChildren() - * - * @return Part same as self::current() - */ - #[ReturnTypeWillChange] - public function getChildren() - { - return $this->current(); - } - - /** - * implements Iterator::valid() - * - * @return bool check if there's a current element - */ - #[ReturnTypeWillChange] - public function valid() - { - if ($this->countParts === null) { - $this->countParts(); - } - return $this->iterationPos && $this->iterationPos <= $this->countParts; - } - - /** - * implements Iterator::next() - */ - #[ReturnTypeWillChange] - public function next() - { - ++$this->iterationPos; - } - - /** - * implements Iterator::key() - * - * @return string key/number of current part - */ - #[ReturnTypeWillChange] - public function key() - { - return $this->iterationPos; - } - - /** - * implements Iterator::current() - * - * @return Part current part - */ - #[ReturnTypeWillChange] - public function current() - { - return $this->getPart($this->iterationPos); - } - - /** - * implements Iterator::rewind() - */ - #[ReturnTypeWillChange] - public function rewind() - { - $this->countParts(); - $this->iterationPos = 1; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Part/Exception/ExceptionInterface.php b/lib/laminas/laminas-mail/src/Storage/Part/Exception/ExceptionInterface.php deleted file mode 100644 index abebe1c35..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Part/Exception/ExceptionInterface.php +++ /dev/null @@ -1,9 +0,0 @@ -fh = $fh; - if (isset($params['startPos'])) { - fseek($this->fh, $params['startPos']); - } - $header = ''; - $endPos = $params['endPos'] ?? null; - while (($endPos === null || ftell($this->fh) < $endPos) && trim($line = fgets($this->fh))) { - $header .= $line; - } - - if (isset($params['EOL'])) { - $this->headers = Headers::fromString($header, $params['EOL']); - } else { - $this->headers = Headers::fromString($header); - } - - $this->contentPos[0] = ftell($this->fh); - if ($endPos !== null) { - $this->contentPos[1] = $endPos; - } else { - fseek($this->fh, 0, SEEK_END); - $this->contentPos[1] = ftell($this->fh); - } - if (! $this->isMultipart()) { - return; - } - - $boundary = $this->getHeaderField('content-type', 'boundary'); - if (! $boundary) { - throw new Exception\RuntimeException('no boundary found in content type to split message'); - } - - $part = []; - $pos = $this->contentPos[0]; - fseek($this->fh, $pos); - while (! feof($this->fh) && ($endPos === null || $pos < $endPos)) { - $line = fgets($this->fh); - if ($line === false) { - if (feof($this->fh)) { - break; - } - throw new Exception\RuntimeException('error reading file'); - } - - $lastPos = $pos; - $pos = ftell($this->fh); - $line = trim($line); - - if ($line == '--' . $boundary) { - if ($part) { - // not first part - $part[1] = $lastPos; - $this->partPos[] = $part; - } - $part = [$pos]; - } elseif ($line == '--' . $boundary . '--') { - $part[1] = $lastPos; - $this->partPos[] = $part; - break; - } - } - $this->countParts = count($this->partPos); - } - - /** - * Body of part - * - * If part is multipart the raw content of this part with all sub parts is returned - * - * @param resource $stream Optional - * @return string body - */ - public function getContent($stream = null) - { - fseek($this->fh, $this->contentPos[0]); - if ($stream !== null) { - return stream_copy_to_stream($this->fh, $stream, $this->contentPos[1] - $this->contentPos[0]); - } - $length = $this->contentPos[1] - $this->contentPos[0]; - return $length < 1 ? '' : fread($this->fh, $length); - } - - /** - * Return size of part - * - * Quite simple implemented currently (not decoding). Handle with care. - * - * @return int size - */ - public function getSize() - { - return $this->contentPos[1] - $this->contentPos[0]; - } - - /** - * Get part of multipart message - * - * @param int $num number of part starting with 1 for first part - * @throws Exception\RuntimeException - * @return Part wanted part - */ - public function getPart($num) - { - --$num; - if (! isset($this->partPos[$num])) { - throw new Exception\RuntimeException('part not found'); - } - - return new static([ - 'file' => $this->fh, - 'startPos' => $this->partPos[$num][0], - 'endPos' => $this->partPos[$num][1], - ]); - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Part/PartInterface.php b/lib/laminas/laminas-mail/src/Storage/Part/PartInterface.php deleted file mode 100644 index 1b8fe0855..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Part/PartInterface.php +++ /dev/null @@ -1,118 +0,0 @@ - firstPart, partname => value] - * @throws Exception\ExceptionInterface - */ - public function getHeaderField($name, $wantedPart = '0', $firstName = '0'); - - /** - * Getter for mail headers - name is matched in lowercase - * - * This getter is short for PartInterface::getHeader($name, 'string') - * - * @see PartInterface::getHeader() - * - * @param string $name header name - * @return string value of header - * @throws Exception\ExceptionInterface - */ - public function __get($name); - - /** - * magic method to get content of part - * - * @return string content - */ - public function __toString(); -} diff --git a/lib/laminas/laminas-mail/src/Storage/Pop3.php b/lib/laminas/laminas-mail/src/Storage/Pop3.php deleted file mode 100644 index 633f3161f..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Pop3.php +++ /dev/null @@ -1,300 +0,0 @@ -protocol->status($count, $octets); - return (int) $count; - } - - /** - * get a list of messages with number and size - * - * @param int $id number of message - * @return int|array size of given message of list with all messages as array(num => size) - * @throws \Laminas\Mail\Protocol\Exception\ExceptionInterface - */ - public function getSize($id = 0) - { - $id = $id ?: null; - return $this->protocol->getList($id); - } - - /** - * Fetch a message - * - * @param int $id number of message - * @return Message - * @throws \Laminas\Mail\Protocol\Exception\ExceptionInterface - */ - public function getMessage($id) - { - $bodyLines = 0; - $message = $this->protocol->top($id, $bodyLines, true); - - return new $this->messageClass([ - 'handler' => $this, - 'id' => $id, - 'headers' => $message, - 'noToplines' => $bodyLines < 1, - ]); - } - - /** - * Get raw header of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message header - * @param int $topLines include this many lines with header (after an empty line) - * @return string raw header - * @throws \Laminas\Mail\Protocol\Exception\ExceptionInterface - * @throws ExceptionInterface - */ - public function getRawHeader($id, $part = null, $topLines = 0) - { - if ($part !== null) { - // TODO: implement - throw new Exception\RuntimeException('not implemented'); - } - - return $this->protocol->top($id, 0, true); - } - - /** - * Get raw content of message or part - * - * @param int $id number of message - * @param null|array|string $part path to part or null for message content - * @return string raw content - * @throws \Laminas\Mail\Protocol\Exception\ExceptionInterface - * @throws ExceptionInterface - */ - public function getRawContent($id, $part = null) - { - if ($part !== null) { - // TODO: implement - throw new Exception\RuntimeException('not implemented'); - } - - $content = $this->protocol->retrieve($id); - // TODO: find a way to avoid decoding the headers - $headers = null; // "Declare" variable since it's passed by reference - $body = null; // "Declare" variable before first usage. - Mime\Decode::splitMessage($content, $headers, $body); - return $body; - } - - /** - * create instance with parameters - * Supported parameters are - * - host hostname or ip address of POP3 server - * - user username - * - password password for user 'username' [optional, default = ''] - * - port port for POP3 server [optional, default = 110] - * - ssl 'SSL' or 'TLS' for secure sockets - * - * @param array|object|Protocol\Pop3 $params mail reader specific - * parameters or configured Pop3 protocol object - * @throws InvalidArgumentException - * @throws RuntimeException - */ - public function __construct($params) - { - $this->has['fetchPart'] = false; - $this->has['top'] = null; - $this->has['uniqueid'] = null; - - if ($params instanceof Protocol\Pop3) { - $this->protocol = $params; - return; - } - - $params = ParamsNormalizer::normalizeParams($params); - - if (! isset($params['user'])) { - throw new InvalidArgumentException('need at least user in params'); - } - - $host = $params['host'] ?? 'localhost'; - $password = $params['password'] ?? ''; - $port = $params['port'] ?? null; - $ssl = $params['ssl'] ?? false; - - if (null !== $port) { - $port = (int) $port; - } - - if (! is_string($ssl)) { - $ssl = (bool) $ssl; - } - - $this->protocol = new Protocol\Pop3(); - - if (array_key_exists('novalidatecert', $params)) { - $this->protocol->setNoValidateCert((bool) $params['novalidatecert']); - } - - $this->protocol->connect((string) $host, $port, $ssl); - $this->protocol->login((string) $params['user'], (string) $password); - } - - /** - * Close resource for mail lib. If you need to control, when the resource - * is closed. Otherwise the destructor would call this. - */ - public function close() - { - $this->protocol->logout(); - } - - /** - * Keep the server busy. - * - * @throws RuntimeException - */ - public function noop() - { - $this->protocol->noop(); - } - - /** - * Remove a message from server. If you're doing that from a web environment - * you should be careful and use a uniqueid as parameter if possible to - * identify the message. - * - * @param int $id number of message - * @throws RuntimeException - */ - public function removeMessage($id) - { - $this->protocol->delete($id); - } - - /** - * get unique id for one or all messages - * - * if storage does not support unique ids it's the same as the message number - * - * @param int|null $id message number - * @return array|string message number for given message or all messages as array - * @throws ExceptionInterface - */ - public function getUniqueId($id = null) - { - if (! $this->hasUniqueid) { - if ($id) { - return $id; - } - $count = $this->countMessages(); - if ($count < 1) { - return []; - } - $range = range(1, $count); - return array_combine($range, $range); - } - - return $this->protocol->uniqueid($id); - } - - /** - * get a message number from a unique id - * - * I.e. if you have a webmailer that supports deleting messages you should use unique ids - * as parameter and use this method to translate it to message number right before calling removeMessage() - * - * @param string $id unique id - * @throws InvalidArgumentException - * @return int message number - */ - public function getNumberByUniqueId($id) - { - if (! $this->hasUniqueid) { - return $id; - } - - $ids = $this->getUniqueId(); - foreach ($ids as $k => $v) { - if ($v == $id) { - return $k; - } - } - - throw new InvalidArgumentException('unique id not found'); - } - - /** - * Special handling for hasTop and hasUniqueid. The headers of the first message is - * retrieved if Top wasn't needed/tried yet. - * - * @see AbstractStorage::__get() - * - * @param string $var - * @return null|string - */ - public function __get($var) - { - $result = parent::__get($var); - if ($result !== null) { - return $result; - } - - if (strtolower($var) == 'hastop') { - if ($this->protocol->hasTop === null) { - // need to make a real call, because not all server are honest in their capas - try { - $this->protocol->top(1, 0, false); - } catch (MailException\ExceptionInterface) { - // ignoring error - } - } - $this->has['top'] = $this->protocol->hasTop; - return $this->protocol->hasTop; - } - - if (strtolower($var) == 'hasuniqueid') { - $id = null; - try { - $id = $this->protocol->uniqueid(1); - } catch (MailException\ExceptionInterface) { - // ignoring error - } - $this->has['uniqueid'] = (bool) $id; - return $this->has['uniqueid']; - } - - return $result; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Writable/Maildir.php b/lib/laminas/laminas-mail/src/Storage/Writable/Maildir.php deleted file mode 100644 index fe8a162a9..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Writable/Maildir.php +++ /dev/null @@ -1,1023 +0,0 @@ -create) - && isset($params->dirname) - && ! file_exists($params->dirname . DIRECTORY_SEPARATOR . 'cur') - ) { - self::initMaildir($params->dirname); - } - - parent::__construct($params); - } - - /** - * create a new folder - * - * This method also creates parent folders if necessary. Some mail storages may restrict, which folder - * may be used as parent or which chars may be used in the folder name - * - * @param string $name global name of folder, local name if $parentFolder is set - * @param string|Folder $parentFolder parent of new folder, else root folder is parent - * @throws RuntimeException - * @return string only used internally (new created maildir) - */ - public function createFolder($name, $parentFolder = null) - { - if ($parentFolder instanceof Folder) { - $folder = $parentFolder->getGlobalName() . $this->delim . $name; - } elseif ($parentFolder !== null) { - $folder = rtrim($parentFolder, $this->delim) . $this->delim . $name; - } else { - $folder = $name; - } - - $folder = trim($folder, $this->delim); - - // first we check if we try to create a folder that does exist - $exists = null; - try { - $exists = $this->getFolders($folder); - } catch (MailException\ExceptionInterface) { - // ok - } - if ($exists) { - throw new StorageException\RuntimeException('folder already exists'); - } - - if (str_contains($folder, $this->delim . $this->delim)) { - throw new StorageException\RuntimeException('invalid name - folder parts may not be empty'); - } - - if (str_starts_with($folder, 'INBOX' . $this->delim)) { - $folder = substr($folder, 6); - } - - $fulldir = $this->rootdir . '.' . $folder; - - // check if we got tricked and would create a dir outside of the rootdir or not as direct child - if ( - str_contains($folder, DIRECTORY_SEPARATOR) || str_contains($folder, '/') - || dirname($fulldir) . DIRECTORY_SEPARATOR != $this->rootdir - ) { - throw new StorageException\RuntimeException('invalid name - no directory separator allowed in folder name'); - } - - // has a parent folder? - $parent = null; - if (strpos($folder, $this->delim)) { - // let's see if the parent folder exists - $parent = substr($folder, 0, strrpos($folder, $this->delim)); - try { - $this->getFolders($parent); - } catch (MailException\ExceptionInterface) { - // does not - create parent folder - $this->createFolder($parent); - } - } - - ErrorHandler::start(); - if (! mkdir($fulldir) || ! mkdir($fulldir . DIRECTORY_SEPARATOR . 'cur')) { - $error = ErrorHandler::stop(); - throw new StorageException\RuntimeException( - 'error while creating new folder, may be created incompletely', - 0, - $error - ); - } - ErrorHandler::stop(); - - mkdir($fulldir . DIRECTORY_SEPARATOR . 'new'); - mkdir($fulldir . DIRECTORY_SEPARATOR . 'tmp'); - - $localName = $parent ? substr($folder, strlen($parent) + 1) : $folder; - $this->getFolders($parent)->$localName = new Folder($localName, $folder, true); - - return $fulldir; - } - - /** - * remove a folder - * - * @param string|Folder $name name or instance of folder - * @throws RuntimeException - */ - public function removeFolder($name) - { - // TODO: This could fail in the middle of the task, which is not optimal. - // But there is no defined standard way to mark a folder as removed and there is no atomar fs-op - // to remove a directory. Also moving the folder to a/the trash folder is not possible, as - // all parent folders must be created. What we could do is add a dash to the front of the - // directory name and it should be ignored as long as other processes obey the standard. - - if ($name instanceof Folder) { - $name = $name->getGlobalName(); - } - - $name = trim($name, $this->delim); - if (str_starts_with($name, 'INBOX' . $this->delim)) { - $name = substr($name, 6); - } - - // check if folder exists and has no children - if (! $this->getFolders($name)->isLeaf()) { - throw new StorageException\RuntimeException('delete children first'); - } - - if ($name == 'INBOX' || $name == DIRECTORY_SEPARATOR || $name == '/') { - throw new StorageException\RuntimeException('wont delete INBOX'); - } - - if ($name == $this->getCurrentFolder()) { - throw new StorageException\RuntimeException('wont delete selected folder'); - } - - foreach (['tmp', 'new', 'cur', '.'] as $subdir) { - $dir = $this->rootdir . '.' . $name . DIRECTORY_SEPARATOR . $subdir; - if (! file_exists($dir)) { - continue; - } - $dh = opendir($dir); - if (! $dh) { - throw new StorageException\RuntimeException("error opening $subdir"); - } - while (($entry = readdir($dh)) !== false) { - if ($entry == '.' || $entry == '..') { - continue; - } - if (! unlink($dir . DIRECTORY_SEPARATOR . $entry)) { - throw new StorageException\RuntimeException("error cleaning $subdir"); - } - } - closedir($dh); - if ($subdir !== '.') { - if (! rmdir($dir)) { - throw new StorageException\RuntimeException("error removing $subdir"); - } - } - } - - if (! rmdir($this->rootdir . '.' . $name)) { - // at least we should try to make it a valid maildir again - mkdir($this->rootdir . '.' . $name . DIRECTORY_SEPARATOR . 'cur'); - throw new StorageException\RuntimeException("error removing maindir"); - } - - $parent = strpos($name, $this->delim) ? substr($name, 0, strrpos($name, $this->delim)) : null; - $localName = $parent ? substr($name, strlen($parent) + 1) : $name; - unset($this->getFolders($parent)->$localName); - } - - /** - * rename and/or move folder - * - * The new name has the same restrictions as in createFolder() - * - * @param string|Folder $oldName name or instance of folder - * @param string $newName new global name of folder - * @throws RuntimeException - */ - public function renameFolder($oldName, $newName) - { - // TODO: This is also not atomar and has similar problems as removeFolder() - - if ($oldName instanceof Folder) { - $oldName = $oldName->getGlobalName(); - } - - $oldName = trim($oldName, $this->delim); - if (str_starts_with($oldName, 'INBOX' . $this->delim)) { - $oldName = substr($oldName, 6); - } - - $newName = trim($newName, $this->delim); - if (str_starts_with($newName, 'INBOX' . $this->delim)) { - $newName = substr($newName, 6); - } - - if (str_starts_with($newName, $oldName . $this->delim)) { - throw new StorageException\RuntimeException('new folder cannot be a child of old folder'); - } - - // check if folder exists and has no children - $folder = $this->getFolders($oldName); - - if ($oldName == 'INBOX' || $oldName == DIRECTORY_SEPARATOR || $oldName == '/') { - throw new StorageException\RuntimeException('wont rename INBOX'); - } - - if ($oldName == $this->getCurrentFolder()) { - throw new StorageException\RuntimeException('wont rename selected folder'); - } - - $newdir = $this->createFolder($newName); - - if (! $folder->isLeaf()) { - foreach ($folder as $k => $v) { - $this->renameFolder($v->getGlobalName(), $newName . $this->delim . $k); - } - } - - $olddir = $this->rootdir . '.' . $folder; - foreach (['tmp', 'new', 'cur'] as $subdir) { - $subdir = DIRECTORY_SEPARATOR . $subdir; - if (! file_exists($olddir . $subdir)) { - continue; - } - // using copy or moving files would be even better - but also much slower - if (! rename($olddir . $subdir, $newdir . $subdir)) { - throw new StorageException\RuntimeException('error while moving ' . $subdir); - } - } - // create a dummy if removing fails - otherwise we can't read it next time - mkdir($olddir . DIRECTORY_SEPARATOR . 'cur'); - $this->removeFolder($oldName); - } - - /** - * create a uniqueid for maildir filename - * - * This is nearly the format defined in the maildir standard. The microtime() call should already - * create a uniqueid, the pid is for multicore/-cpu machine that manage to call this function at the - * exact same time, and uname() gives us the hostname for multiple machines accessing the same storage. - * - * If someone disables posix we create a random number of the same size, so this method should also - * work on Windows - if you manage to get maildir working on Windows. - * Microtime could also be disabled, although I've never seen it. - * - * @return string new uniqueid - */ - protected function createUniqueId() - { - $id = ''; - $id .= microtime(true); - $id .= '.' . getmypid(); - $id .= '.' . php_uname('n'); - - return $id; - } - - /** - * open a temporary maildir file - * - * makes sure tmp/ exists and create a file with a unique name - * you should close the returned filehandle! - * - * @param string $folder name of current folder without leading . - * @throws RuntimeException - * @return array array('dirname' => dir of maildir folder, 'uniq' => unique id, 'filename' => name of create file - * 'handle' => file opened for writing) - */ - protected function createTmpFile($folder = 'INBOX') - { - if ($folder == 'INBOX') { - $tmpdir = $this->rootdir . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR; - } else { - $tmpdir = $this->rootdir . '.' . $folder . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR; - } - if (! file_exists($tmpdir)) { - if (! mkdir($tmpdir)) { - throw new StorageException\RuntimeException('problems creating tmp dir'); - } - } - - // we should retry to create a unique id if a file with the same name exists - // to avoid a script timeout we only wait 1 second (instead of 2) and stop - // after a defined retry count - // if you change this variable take into account that it can take up to $maxTries seconds - // normally we should have a valid unique name after the first try, we're just following the "standard" here - $maxTries = 5; - for ($i = 0; $i < $maxTries; ++$i) { - $uniq = $this->createUniqueId(); - if (! file_exists($tmpdir . $uniq)) { - // here is the race condition! - as defined in the standard - // to avoid having a long time between stat()ing the file and creating it we're opening it here - // to mark the filename as taken - $fh = fopen($tmpdir . $uniq, 'w'); - if (! $fh) { - throw new StorageException\RuntimeException('could not open temp file'); - } - break; - } - sleep(1); - } - - if (! $fh) { - throw new StorageException\RuntimeException( - "tried {$maxTries} unique ids for a temp file, but all were taken - giving up" - ); - } - - return [ - 'dirname' => $this->rootdir . '.' . $folder, - 'uniq' => $uniq, - 'filename' => $tmpdir . $uniq, - 'handle' => $fh, - ]; - } - - /** - * create an info string for filenames with given flags - * - * @param array $flags wanted flags, with the reference you'll get the set - * flags with correct key (= char for flag) - * @return string info string for version 2 filenames including the leading colon - * @throws StorageException\InvalidArgumentException - */ - protected function getInfoString(&$flags) - { - // accessing keys is easier, faster and it removes duplicated flags - $wantedFlags = array_flip($flags); - if (isset($wantedFlags[Storage::FLAG_RECENT])) { - throw new StorageException\InvalidArgumentException('recent flag may not be set'); - } - - $info = ':2,'; - $flags = []; - foreach (Storage\Maildir::$knownFlags as $char => $flag) { - if (! isset($wantedFlags[$flag])) { - continue; - } - $info .= $char; - $flags[$char] = $flag; - unset($wantedFlags[$flag]); - } - - if (! empty($wantedFlags)) { - $wantedFlags = implode(', ', array_keys($wantedFlags)); - throw new StorageException\InvalidArgumentException('unknown flag(s): ' . $wantedFlags); - } - - return $info; - } - - /** - * append a new message to mail storage - * - * @param string|resource $message message as string or stream resource. - * @param null|string|Folder $folder folder for new message, else current - * folder is taken. - * @param null|array $flags set flags for new message, else a default set - * is used. - * @param bool $recent handle this mail as if recent flag has been set, - * should only be used in delivery. - * @throws StorageException\RuntimeException - */ - public function appendMessage($message, $folder = null, $flags = null, $recent = false) - { - if ($this->quota && $this->checkQuota()) { - throw new StorageException\RuntimeException('storage is over quota!'); - } - - if ($folder === null) { - $folder = $this->currentFolder; - } - - if (! $folder instanceof Folder) { - $folder = $this->getFolders($folder); - } - - if ($flags === null) { - $flags = [Storage::FLAG_SEEN]; - } - $info = $this->getInfoString($flags); - $tempFile = $this->createTmpFile($folder->getGlobalName()); - - // TODO: handle class instances for $message - if (is_resource($message) && get_resource_type($message) == 'stream') { - stream_copy_to_stream($message, $tempFile['handle']); - } else { - fwrite($tempFile['handle'], $message); - } - fclose($tempFile['handle']); - - // we're adding the size to the filename for maildir++ - $size = filesize($tempFile['filename']); - if ($size !== false) { - $info = ',S=' . $size . $info; - } - $newFilename = $tempFile['dirname'] . DIRECTORY_SEPARATOR; - $newFilename .= $recent ? 'new' : 'cur'; - $newFilename .= DIRECTORY_SEPARATOR . $tempFile['uniq'] . $info; - - // we're throwing any exception after removing our temp file and saving it to this variable instead - $exception = null; - - if (! link($tempFile['filename'], $newFilename)) { - $exception = new StorageException\RuntimeException('cannot link message file to final dir'); - } - - ErrorHandler::start(E_WARNING); - unlink($tempFile['filename']); - ErrorHandler::stop(); - - if ($exception) { - throw $exception; - } - - $this->files[] = [ - 'uniq' => $tempFile['uniq'], - 'flags' => $flags, - 'filename' => $newFilename, - ]; - if ($this->quota) { - $this->addQuotaEntry((int) $size, 1); - } - } - - /** - * copy an existing message - * - * @param int $id number of message - * @param string|Folder $folder name or instance of targer folder - * @throws RuntimeException - */ - public function copyMessage($id, $folder) - { - if ($this->quota && $this->checkQuota()) { - throw new StorageException\RuntimeException('storage is over quota!'); - } - - if (! $folder instanceof Folder) { - $folder = $this->getFolders($folder); - } - - $filedata = $this->getFileData($id); - $oldFile = $filedata['filename']; - $flags = $filedata['flags']; - - // copied message can't be recent - while (($key = array_search(Storage::FLAG_RECENT, $flags)) !== false) { - unset($flags[$key]); - } - $info = $this->getInfoString($flags); - - // we're creating the copy as temp file before moving to cur/ - $tempFile = $this->createTmpFile($folder->getGlobalName()); - // we don't write directly to the file - fclose($tempFile['handle']); - - // we're adding the size to the filename for maildir++ - $size = filesize($oldFile); - if ($size !== false) { - $info = ',S=' . $size . $info; - } - - $newFile = $tempFile['dirname'] . DIRECTORY_SEPARATOR . 'cur' . DIRECTORY_SEPARATOR . $tempFile['uniq'] . $info; - - // we're throwing any exception after removing our temp file and saving it to this variable instead - $exception = null; - - if (! copy($oldFile, $tempFile['filename'])) { - $exception = new StorageException\RuntimeException('cannot copy message file'); - } elseif (! link($tempFile['filename'], $newFile)) { - $exception = new StorageException\RuntimeException('cannot link message file to final dir'); - } - - ErrorHandler::start(E_WARNING); - unlink($tempFile['filename']); - ErrorHandler::stop(); - - if ($exception) { - throw $exception; - } - - if ( - $folder->getGlobalName() == $this->currentFolder - || ($this->currentFolder == 'INBOX' && $folder->getGlobalName() == '/') - ) { - $this->files[] = [ - 'uniq' => $tempFile['uniq'], - 'flags' => $flags, - 'filename' => $newFile, - ]; - } - - if ($this->quota) { - $this->addQuotaEntry((int) $size, 1); - } - } - - /** - * move an existing message - * - * @param int $id number of message - * @param string|Folder $folder name or instance of targer folder - * @throws RuntimeException - */ - public function moveMessage($id, $folder) - { - if (! $folder instanceof Folder) { - $folder = $this->getFolders($folder); - } - - if ( - $folder->getGlobalName() == $this->currentFolder - || ($this->currentFolder == 'INBOX' && $folder->getGlobalName() == '/') - ) { - throw new StorageException\RuntimeException('target is current folder'); - } - - $filedata = $this->getFileData($id); - $oldFile = $filedata['filename']; - $flags = $filedata['flags']; - - // moved message can't be recent - while (($key = array_search(Storage::FLAG_RECENT, $flags)) !== false) { - unset($flags[$key]); - } - $info = $this->getInfoString($flags); - - // reserving a new name - $tempFile = $this->createTmpFile($folder->getGlobalName()); - fclose($tempFile['handle']); - - // we're adding the size to the filename for maildir++ - $size = filesize($oldFile); - if ($size !== false) { - $info = ',S=' . $size . $info; - } - - $newFile = $tempFile['dirname'] . DIRECTORY_SEPARATOR . 'cur' . DIRECTORY_SEPARATOR . $tempFile['uniq'] . $info; - - // we're throwing any exception after removing our temp file and saving it to this variable instead - $exception = null; - - if (! rename($oldFile, $newFile)) { - $exception = new StorageException\RuntimeException('cannot move message file'); - } - - ErrorHandler::start(E_WARNING); - unlink($tempFile['filename']); - ErrorHandler::stop(); - - if ($exception) { - throw $exception; - } - - unset($this->files[$id - 1]); - // remove the gap - $this->files = array_values($this->files); - } - - /** - * set flags for message - * - * NOTE: this method can't set the recent flag. - * - * @param int $id number of message - * @param array $flags new flags for message - * @throws RuntimeException - */ - public function setFlags($id, $flags) - { - $info = $this->getInfoString($flags); - $filedata = $this->getFileData($id); - - // NOTE: double dirname to make sure we always move to cur. if recent - // flag has been set (message is in new) it will be moved to cur. - $newFilename = dirname($filedata['filename'], 2) - . DIRECTORY_SEPARATOR - . 'cur' - . DIRECTORY_SEPARATOR - . "$filedata[uniq]$info"; - - ErrorHandler::start(); - $test = rename($filedata['filename'], $newFilename); - $error = ErrorHandler::stop(); - if (! $test) { - throw new StorageException\RuntimeException('cannot rename file', 0, $error); - } - - $filedata['flags'] = $flags; - $filedata['filename'] = $newFilename; - - $this->files[$id - 1] = $filedata; - } - - /** - * stub for not supported message deletion - * - * @param int $id - * @throws RuntimeException - */ - public function removeMessage($id) - { - $filename = $this->getFileData($id, 'filename'); - - if ($this->quota) { - $size = filesize($filename); - } - - ErrorHandler::start(); - $test = unlink($filename); - $error = ErrorHandler::stop(); - if (! $test) { - throw new StorageException\RuntimeException('cannot remove message', 0, $error); - } - unset($this->files[$id - 1]); - // remove the gap - $this->files = array_values($this->files); - if ($this->quota) { - $this->addQuotaEntry(0 - (int) $size, -1); - } - } - - /** - * enable/disable quota and set a quota value if wanted or needed - * - * You can enable/disable quota with true/false. If you don't have - * a MDA or want to enforce a quota value you can also set this value - * here. Use array('size' => SIZE_QUOTA, 'count' => MAX_MESSAGE) do - * define your quota. Order of these fields does matter! - * - * @param bool|array $value new quota value - */ - public function setQuota($value) - { - $this->quota = $value; - } - - /** - * get currently set quota - * - * @see \Laminas\Mail\Storage\Writable\Maildir::setQuota() - * - * @param bool $fromStorage - * @throws RuntimeException - * @return bool|array - */ - public function getQuota($fromStorage = false) - { - if ($fromStorage) { - ErrorHandler::start(E_WARNING); - $fh = fopen($this->rootdir . 'maildirsize', 'r'); - $error = ErrorHandler::stop(); - if (! $fh) { - throw new StorageException\RuntimeException('cannot open maildirsize', 0, $error); - } - $definition = fgets($fh); - fclose($fh); - $definition = explode(',', trim($definition)); - $quota = []; - foreach ($definition as $member) { - $key = $member[strlen($member) - 1]; - if ($key == 'S' || $key == 'C') { - $key = $key == 'C' ? 'count' : 'size'; - } - $quota[$key] = substr($member, 0, -1); - } - return $quota; - } - - return $this->quota; - } - - /** - * @see http://www.inter7.com/courierimap/README.maildirquota.html "Calculating maildirsize" - * - * @throws RuntimeException - * @return array - */ - protected function calculateMaildirsize() - { - $timestamps = []; - $messages = 0; - $totalSize = 0; - - if (is_array($this->quota)) { - $quota = $this->quota; - } else { - try { - $quota = $this->getQuota(true); - } catch (StorageException\ExceptionInterface $e) { - throw new StorageException\RuntimeException('no quota definition found', 0, $e); - } - } - - $folders = new RecursiveIteratorIterator($this->getFolders(), RecursiveIteratorIterator::SELF_FIRST); - foreach ($folders as $folder) { - $subdir = $folder->getGlobalName(); - if ($subdir == 'INBOX') { - $subdir = ''; - } else { - $subdir = '.' . $subdir; - } - if ($subdir == 'Trash') { - continue; - } - - foreach (['cur', 'new'] as $subsubdir) { - $dirname = $this->rootdir . $subdir . DIRECTORY_SEPARATOR . $subsubdir . DIRECTORY_SEPARATOR; - if (! file_exists($dirname)) { - continue; - } - // NOTE: we are using mtime instead of "the latest timestamp". The latest would be atime - // and as we are accessing the directory it would make the whole calculation useless. - $timestamps[$dirname] = filemtime($dirname); - - $dh = opendir($dirname); - // NOTE: Should have been checked in constructor. Not throwing an exception here, quotas will - // therefore not be fully enforced, but next request will fail anyway, if problem persists. - if (! $dh) { - continue; - } - - while (($entry = readdir()) !== false) { - if ($entry[0] == '.' || ! is_file($dirname . $entry)) { - continue; - } - - if (strpos($entry, ',S=')) { - strtok($entry, '='); - $filesize = strtok(':'); - if (is_numeric($filesize)) { - $totalSize += $filesize; - ++$messages; - continue; - } - } - $size = filesize($dirname . $entry); - if ($size === false) { - // ignore, as we assume file got removed - continue; - } - $totalSize += $size; - ++$messages; - } - } - } - - $tmp = $this->createTmpFile(); - $fh = $tmp['handle']; - $definition = []; - foreach ($quota as $type => $value) { - if ($type == 'size' || $type == 'count') { - $type = $type == 'count' ? 'C' : 'S'; - } - $definition[] = $value . $type; - } - $definition = implode(',', $definition); - fwrite($fh, "$definition\n"); - fwrite($fh, "$totalSize $messages\n"); - fclose($fh); - rename($tmp['filename'], $this->rootdir . 'maildirsize'); - foreach ($timestamps as $dir => $timestamp) { - if ($timestamp < filemtime($dir)) { - unlink($this->rootdir . 'maildirsize'); - break; - } - } - - return [ - 'size' => $totalSize, - 'count' => $messages, - 'quota' => $quota, - ]; - } - - /** - * @see http://www.inter7.com/courierimap/README.maildirquota.html "Calculating the quota for a Maildir++" - * - * @param bool $forceRecalc - * @return array - */ - protected function calculateQuota($forceRecalc = false) - { - $fh = null; - $totalSize = 0; - $messages = 0; - $maildirsize = ''; - if ( - ! $forceRecalc - && file_exists($this->rootdir . 'maildirsize') - && filesize($this->rootdir . 'maildirsize') < 5120 - ) { - $fh = fopen($this->rootdir . 'maildirsize', 'r'); - } - if ($fh) { - $maildirsize = fread($fh, 5120); - if (strlen($maildirsize) >= 5120) { - fclose($fh); - $fh = null; - $maildirsize = ''; - } - } - if (! $fh) { - $result = $this->calculateMaildirsize(); - $totalSize = $result['size']; - $messages = $result['count']; - $quota = $result['quota']; - } else { - $maildirsize = explode("\n", $maildirsize); - if (is_array($this->quota)) { - $quota = $this->quota; - } else { - $definition = explode(',', $maildirsize[0]); - $quota = []; - foreach ($definition as $member) { - $key = $member[strlen($member) - 1]; - if ($key == 'S' || $key == 'C') { - $key = $key == 'C' ? 'count' : 'size'; - } - $quota[$key] = substr($member, 0, -1); - } - } - unset($maildirsize[0]); - foreach ($maildirsize as $line) { - [$size, $count] = explode(' ', trim($line)); - $totalSize += $size; - $messages += $count; - } - } - - $overQuota = false; - $overQuota = $overQuota || (isset($quota['size']) && $totalSize > $quota['size']); - $overQuota = $overQuota || (isset($quota['count']) && $messages > $quota['count']); - // NOTE: $maildirsize equals false if it wasn't set (AKA we recalculated) or it's only - // one line, because $maildirsize[0] gets unsetted. - // Also we're using local time to calculate the 15 minute offset. Touching a file just for known the - // local time of the file storage isn't worth the hassle. - if ($overQuota && ($maildirsize || filemtime($this->rootdir . 'maildirsize') > time() - 900)) { - $result = $this->calculateMaildirsize(); - $totalSize = $result['size']; - $messages = $result['count']; - $quota = $result['quota']; - $overQuota = false; - $overQuota = $overQuota || (isset($quota['size']) && $totalSize > $quota['size']); - $overQuota = $overQuota || (isset($quota['count']) && $messages > $quota['count']); - } - - if ($fh) { - // TODO is there a safe way to keep the handle open for writing? - fclose($fh); - } - - return [ - 'size' => $totalSize, - 'count' => $messages, - 'quota' => $quota, - 'over_quota' => $overQuota, - ]; - } - - /** - * @param int $size - * @param int $count - * @return void - */ - protected function addQuotaEntry($size, $count = 1) - { - // if (! file_exists($this->rootdir . 'maildirsize')) { - // TODO: should get file handler from calculateQuota - // } - file_put_contents($this->rootdir . 'maildirsize', "$size $count\n", FILE_APPEND); - } - - /** - * check if storage is currently over quota - * - * @see calculateQuota() - * - * @param bool $detailedResponse return known data of quota and current size and message count - * @param bool $forceRecalc - * @return bool|array over quota state or detailed response - */ - public function checkQuota($detailedResponse = false, $forceRecalc = false) - { - $result = $this->calculateQuota($forceRecalc); - return $detailedResponse ? $result : $result['over_quota']; - } -} diff --git a/lib/laminas/laminas-mail/src/Storage/Writable/WritableInterface.php b/lib/laminas/laminas-mail/src/Storage/Writable/WritableInterface.php deleted file mode 100644 index 9a005ba3b..000000000 --- a/lib/laminas/laminas-mail/src/Storage/Writable/WritableInterface.php +++ /dev/null @@ -1,86 +0,0 @@ -from; - } - - /** - * Set MAIL FROM - * - * @param string $from - */ - public function setFrom($from) - { - $this->from = (string) $from; - } - - /** - * Get RCPT TO - * - * @return string|null - */ - public function getTo() - { - return $this->to; - } - - /** - * Set RCPT TO - * - * @param string $to - */ - public function setTo($to) - { - $this->to = $to; - } -} diff --git a/lib/laminas/laminas-mail/src/Transport/Exception/DomainException.php b/lib/laminas/laminas-mail/src/Transport/Exception/DomainException.php deleted file mode 100644 index d92b9d122..000000000 --- a/lib/laminas/laminas-mail/src/Transport/Exception/DomainException.php +++ /dev/null @@ -1,12 +0,0 @@ - File::class, - 'inmemory' => InMemory::class, - 'memory' => InMemory::class, - 'null' => InMemory::class, - 'sendmail' => Sendmail::class, - 'smtp' => Smtp::class, - ]; - - /** - * @param array $spec - * @return TransportInterface - * @throws Exception\InvalidArgumentException - * @throws Exception\DomainException - */ - public static function create($spec = []) - { - if ($spec instanceof Traversable) { - $spec = ArrayUtils::iteratorToArray($spec); - } - - if (! is_array($spec)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects an array or Traversable argument; received "%s"', - __METHOD__, - is_object($spec) ? $spec::class : gettype($spec) - )); - } - - $type = $spec['type'] ?? 'sendmail'; - - $normalizedType = strtolower($type); - - if (isset(static::$classMap[$normalizedType])) { - $type = static::$classMap[$normalizedType]; - } - - if (! class_exists($type)) { - throw new Exception\DomainException(sprintf( - '%s expects the "type" attribute to resolve to an existing class; received "%s"', - __METHOD__, - $type - )); - } - - $transport = new $type(); - - if (! $transport instanceof TransportInterface) { - throw new Exception\DomainException(sprintf( - '%s expects the "type" attribute to resolve to a valid %s instance; received "%s"', - __METHOD__, - TransportInterface::class, - $type - )); - } - - if ($transport instanceof Smtp && isset($spec['options'])) { - $transport->setOptions(new SmtpOptions($spec['options'])); - } - - if ($transport instanceof File && isset($spec['options'])) { - $transport->setOptions(new FileOptions($spec['options'])); - } - - return $transport; - } -} diff --git a/lib/laminas/laminas-mail/src/Transport/File.php b/lib/laminas/laminas-mail/src/Transport/File.php deleted file mode 100644 index aef7f15e1..000000000 --- a/lib/laminas/laminas-mail/src/Transport/File.php +++ /dev/null @@ -1,89 +0,0 @@ -setOptions($options); - } - - /** - * @return FileOptions - */ - public function getOptions() - { - return $this->options; - } - - /** - * Sets options - */ - public function setOptions(FileOptions $options) - { - $this->options = $options; - } - - /** - * Saves e-mail message to a file - * - * @throws Exception\RuntimeException On not writable target directory or on file_put_contents() failure. - */ - public function send(Message $message) - { - $options = $this->options; - $filename = $options->getCallback()($this); - $file = $options->getPath() . DIRECTORY_SEPARATOR . $filename; - $email = $message->toString(); - - if (false === file_put_contents($file, $email)) { - throw new Exception\RuntimeException(sprintf( - 'Unable to write mail to file (directory "%s")', - $options->getPath() - )); - } - - $this->lastFile = $file; - } - - /** - * Get the name of the last file written to - * - * @return string - */ - public function getLastFile() - { - return $this->lastFile; - } -} diff --git a/lib/laminas/laminas-mail/src/Transport/FileOptions.php b/lib/laminas/laminas-mail/src/Transport/FileOptions.php deleted file mode 100644 index 6f21cb878..000000000 --- a/lib/laminas/laminas-mail/src/Transport/FileOptions.php +++ /dev/null @@ -1,94 +0,0 @@ -path = $path; - return $this; - } - - /** - * Get path - * - * If none is set, uses value from sys_get_temp_dir() - * - * @return string - */ - public function getPath() - { - if (null === $this->path) { - $this->setPath(sys_get_temp_dir()); - } - return $this->path; - } - - /** - * Set callback used to generate a file name - * - * @param callable $callback - * @throws InvalidArgumentException - * @return FileOptions - */ - public function setCallback($callback) - { - if (! is_callable($callback)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects a valid callback; received "%s"', - __METHOD__, - is_object($callback) ? $callback::class : gettype($callback) - )); - } - $this->callback = $callback; - return $this; - } - - /** - * Get callback used to generate a file name - * - * @return callable - */ - public function getCallback() - { - if (null === $this->callback) { - $this->setCallback(static fn() => 'LaminasMail_' . time() . '_' . mt_rand() . '.eml'); - } - return $this->callback; - } -} diff --git a/lib/laminas/laminas-mail/src/Transport/InMemory.php b/lib/laminas/laminas-mail/src/Transport/InMemory.php deleted file mode 100644 index 93be0d9a2..000000000 --- a/lib/laminas/laminas-mail/src/Transport/InMemory.php +++ /dev/null @@ -1,36 +0,0 @@ -lastMessage = $message; - } - - /** - * Get the last message sent. - * - * @return null|Message - */ - public function getLastMessage() - { - return $this->lastMessage; - } -} diff --git a/lib/laminas/laminas-mail/src/Transport/Sendmail.php b/lib/laminas/laminas-mail/src/Transport/Sendmail.php deleted file mode 100644 index aae76f49b..000000000 --- a/lib/laminas/laminas-mail/src/Transport/Sendmail.php +++ /dev/null @@ -1,342 +0,0 @@ -setParameters($parameters); - } - $this->callable = [$this, 'mailHandler']; - } - - /** - * Set sendmail parameters - * - * Used to populate the additional_parameters argument to mail() - * - * @param null|string|array|Traversable $parameters - * @throws InvalidArgumentException - * @return Sendmail - */ - public function setParameters($parameters) - { - if ($parameters === null || is_string($parameters)) { - $this->parameters = $parameters; - return $this; - } - - if (! is_array($parameters) && ! $parameters instanceof Traversable) { - throw new InvalidArgumentException(sprintf( - '%s expects a string, array, or Traversable object of parameters; received "%s"', - __METHOD__, - is_object($parameters) ? $parameters::class : gettype($parameters) - )); - } - - $string = ''; - foreach ($parameters as $param) { - $string .= ' ' . $param; - } - - $this->parameters = trim($string); - return $this; - } - - /** - * Set callback to use for mail - * - * Primarily for testing purposes, but could be used to curry arguments. - * - * @param callable $callable - * @throws InvalidArgumentException - * @return Sendmail - */ - public function setCallable($callable) - { - if (! is_callable($callable)) { - throw new InvalidArgumentException(sprintf( - '%s expects a callable argument; received "%s"', - __METHOD__, - is_object($callable) ? $callable::class : gettype($callable) - )); - } - $this->callable = $callable; - return $this; - } - - /** - * Send a message - */ - public function send(Mail\Message $message) - { - $to = $this->prepareRecipients($message); - $subject = $this->prepareSubject($message); - $body = $this->prepareBody($message); - $headers = $this->prepareHeaders($message); - $params = $this->prepareParameters($message); - - // On *nix platforms, we need to replace \r\n with \n - // sendmail is not an SMTP server, it is a unix command - it expects LF - if (PHP_VERSION_ID < 80000 && ! $this->isWindowsOs()) { - $to = str_replace("\r\n", "\n", $to); - $subject = str_replace("\r\n", "\n", $subject); - $body = str_replace("\r\n", "\n", $body); - $headers = str_replace("\r\n", "\n", $headers); - } - - ($this->callable)($to, $subject, $body, $headers, $params); - } - - /** - * Prepare recipients list - * - * @throws RuntimeException - * @return string - */ - protected function prepareRecipients(Mail\Message $message) - { - $headers = $message->getHeaders(); - - $hasTo = $headers->has('to'); - if (! $hasTo && ! $headers->has('cc') && ! $headers->has('bcc')) { - throw new RuntimeException( - 'Invalid email; contains no at least one of "To", "Cc", and "Bcc" header' - ); - } - - if (! $hasTo) { - return ''; - } - - /** @var Mail\Header\To $to */ - $to = $headers->get('to'); - $list = $to->getAddressList(); - if (0 == count($list)) { - throw new RuntimeException('Invalid "To" header; contains no addresses'); - } - - // If not on Windows, return normal string - if (! $this->isWindowsOs()) { - return $to->getFieldValue(HeaderInterface::FORMAT_ENCODED); - } - - // Otherwise, return list of emails - $addresses = []; - foreach ($list as $address) { - $addresses[] = $address->getEmail(); - } - $addresses = implode(', ', $addresses); - return $addresses; - } - - /** - * Prepare the subject line string - * - * @return string - */ - protected function prepareSubject(Mail\Message $message) - { - $headers = $message->getHeaders(); - if (! $headers->has('subject')) { - return; - } - $header = $headers->get('subject'); - return $header->getFieldValue(HeaderInterface::FORMAT_ENCODED); - } - - /** - * Prepare the body string - * - * @return string - */ - protected function prepareBody(Mail\Message $message) - { - if (! $this->isWindowsOs()) { - // *nix platforms can simply return the body text - return $message->getBodyText(); - } - - // On windows, lines beginning with a full stop need to be fixed - $text = $message->getBodyText(); - $text = str_replace("\n.", "\n..", $text); - return $text; - } - - /** - * Prepare the textual representation of headers - * - * @return string - */ - protected function prepareHeaders(Mail\Message $message) - { - // Strip the "to" and "subject" headers - $headers = clone $message->getHeaders(); - $headers->removeHeader('To'); - $headers->removeHeader('Subject'); - - /** @var Mail\Header\From $from Sanitize the From header*/ - $from = $headers->get('From'); - if ($from) { - foreach ($from->getAddressList() as $address) { - if (str_contains($address->getEmail(), '\\"')) { - throw new RuntimeException('Potential code injection in From header'); - } - } - } - return $headers->toString(); - } - - /** - * Prepare additional_parameters argument - * - * Basically, overrides the MAIL FROM envelope with either the Sender or - * From address. - * - * @return string - */ - protected function prepareParameters(Mail\Message $message) - { - if ($this->isWindowsOs()) { - return; - } - - $parameters = (string) $this->parameters; - if (preg_match('/(^| )\-f.+/', $parameters)) { - return $parameters; - } - - $sender = $message->getSender(); - if ($sender instanceof AddressInterface) { - return $parameters . ' -f' . escapeshellarg($sender->getEmail()); - } - - $from = $message->getFrom(); - if (count($from)) { - $from->rewind(); - $sender = $from->current(); - return $parameters . ' -f' . escapeshellarg($sender->getEmail()); - } - - return $parameters; - } - - /** - * Send mail using PHP native mail() - * - * @param string $to - * @param string $subject - * @param string $message - * @param string $headers - * @param null|string $parameters - * @throws RuntimeException - */ - public function mailHandler($to, $subject, $message, $headers, $parameters) - { - set_error_handler([$this, 'handleMailErrors']); - if ($parameters === null) { - $result = mail($to, $subject, $message, $headers); - } else { - $result = mail($to, $subject, $message, $headers, $parameters); - } - restore_error_handler(); - - if ($this->errstr !== null || ! $result) { - $errstr = $this->errstr; - if (empty($errstr)) { - $errstr = 'Unknown error'; - } - throw new RuntimeException('Unable to send mail: ' . $errstr); - } - } - - /** - * Temporary error handler for PHP native mail(). - * - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param string $errline - * @param array $errcontext - * @return bool always true - */ - public function handleMailErrors($errno, $errstr, $errfile = null, $errline = null, ?array $errcontext = null) - { - $this->errstr = $errstr; - return true; - } - - /** - * Is this a windows OS? - * - * @return bool - */ - protected function isWindowsOs() - { - if (! $this->operatingSystem) { - $this->operatingSystem = strtoupper(substr(PHP_OS, 0, 3)); - } - return $this->operatingSystem == 'WIN'; - } -} diff --git a/lib/laminas/laminas-mail/src/Transport/Smtp.php b/lib/laminas/laminas-mail/src/Transport/Smtp.php deleted file mode 100644 index 2188b37f2..000000000 --- a/lib/laminas/laminas-mail/src/Transport/Smtp.php +++ /dev/null @@ -1,385 +0,0 @@ -setOptions($options); - } - - /** - * Set options - * - * @return Smtp - */ - public function setOptions(SmtpOptions $options) - { - $this->options = $options; - return $this; - } - - /** - * Get options - * - * @return SmtpOptions - */ - public function getOptions() - { - return $this->options; - } - - /** - * Set options - */ - public function setEnvelope(Envelope $envelope) - { - $this->envelope = $envelope; - } - - /** - * Get envelope - * - * @return Envelope|null - */ - public function getEnvelope() - { - return $this->envelope; - } - - /** - * Set plugin manager for obtaining SMTP protocol connection - * - * @throws Exception\InvalidArgumentException - * @return Smtp - */ - public function setPluginManager(Protocol\SmtpPluginManager $plugins) - { - $this->plugins = $plugins; - return $this; - } - - /** - * Get plugin manager for loading SMTP protocol connection - * - * @return Protocol\SmtpPluginManager - */ - public function getPluginManager() - { - if (null === $this->plugins) { - $this->setPluginManager(new Protocol\SmtpPluginManager(new ServiceManager())); - } - return $this->plugins; - } - - /** - * Set the automatic disconnection when destruct - * - * @param bool $flag - * @return Smtp - */ - public function setAutoDisconnect($flag) - { - $this->autoDisconnect = (bool) $flag; - return $this; - } - - /** - * Get the automatic disconnection value - * - * @return bool - */ - public function getAutoDisconnect() - { - return $this->autoDisconnect; - } - - /** - * Return an SMTP connection - * - * @param string $name - * @return Protocol\Smtp - */ - public function plugin($name, ?array $options = null) - { - return $this->getPluginManager()->get($name, $options); - } - - /** - * Class destructor to ensure all open connections are closed - */ - public function __destruct() - { - $connection = $this->getConnection(); - if (! $connection instanceof Protocol\Smtp) { - return; - } - - try { - $connection->quit(); - } catch (ProtocolException\ExceptionInterface) { - // ignore - } - - if ($this->autoDisconnect) { - $connection->disconnect(); - } - } - - /** - * Sets the connection protocol instance - */ - public function setConnection(Protocol\AbstractProtocol $connection) - { - $this->connection = $connection; - if ( - $connection instanceof Protocol\Smtp - && ($this->getOptions()->getConnectionTimeLimit() !== null) - ) { - $connection->setUseCompleteQuit(false); - } - } - - /** - * Gets the connection protocol instance - * - * @return null|Protocol\Smtp - */ - public function getConnection() - { - $timeLimit = $this->getOptions()->getConnectionTimeLimit(); - if ( - $timeLimit !== null - && $this->connectedTime !== null - && ((time() - $this->connectedTime) > $timeLimit) - ) { - $this->connection = null; - } - return $this->connection; - } - - /** - * Disconnect the connection protocol instance - * - * @return void - */ - public function disconnect() - { - $connection = $this->getConnection(); - if ($connection instanceof Protocol\Smtp) { - $connection->disconnect(); - $this->connectedTime = null; - } - } - - /** - * Send an email via the SMTP connection protocol - * - * The connection via the protocol adapter is made just-in-time to allow a - * developer to add a custom adapter if required before mail is sent. - * - * @throws Exception\RuntimeException - */ - public function send(Message $message) - { - // If sending multiple messages per session use existing adapter - $connection = $this->getConnection(); - - if (! $connection instanceof Protocol\Smtp || ! $connection->hasSession()) { - $connection = $this->connect(); - } else { - // Reset connection to ensure reliable transaction - $connection->rset(); - } - - // Prepare message - $from = $this->prepareFromAddress($message); - $recipients = $this->prepareRecipients($message); - $headers = $this->prepareHeaders($message); - $body = $this->prepareBody($message); - - if ((count($recipients) == 0) && (! empty($headers) || ! empty($body))) { - // Per RFC 2821 3.3 (page 18) - throw new Exception\RuntimeException( - sprintf( - '%s transport expects at least one recipient if the message has at least one header or body', - self::class - ) - ); - } - - // Set sender email address - $connection->mail($from); - - // Set recipient forward paths - foreach ($recipients as $recipient) { - $connection->rcpt($recipient); - } - - // Issue DATA command to client - $connection->data($headers . Headers::EOL . $body); - } - - /** - * Retrieve email address for envelope FROM - * - * @throws Exception\RuntimeException - * @return string - */ - protected function prepareFromAddress(Message $message) - { - if ($this->getEnvelope() && $this->getEnvelope()->getFrom()) { - return $this->getEnvelope()->getFrom(); - } - - $sender = $message->getSender(); - if ($sender instanceof Address\AddressInterface) { - return $sender->getEmail(); - } - - $from = $message->getFrom(); - if (! count($from)) { - // Per RFC 2822 3.6 - throw new Exception\RuntimeException(sprintf( - '%s transport expects either a Sender or at least one From address in the Message; none provided', - self::class - )); - } - - $from->rewind(); - $sender = $from->current(); - return $sender->getEmail(); - } - - /** - * Prepare array of email address recipients - * - * @return array - */ - protected function prepareRecipients(Message $message) - { - if ($this->getEnvelope() && $this->getEnvelope()->getTo()) { - return (array) $this->getEnvelope()->getTo(); - } - - $recipients = []; - foreach ($message->getTo() as $address) { - $recipients[] = $address->getEmail(); - } - foreach ($message->getCc() as $address) { - $recipients[] = $address->getEmail(); - } - foreach ($message->getBcc() as $address) { - $recipients[] = $address->getEmail(); - } - - $recipients = array_unique($recipients); - return $recipients; - } - - /** - * Prepare header string from message - * - * @return string - */ - protected function prepareHeaders(Message $message) - { - $headers = clone $message->getHeaders(); - $headers->removeHeader('Bcc'); - return $headers->toString(); - } - - /** - * Prepare body string from message - * - * @return string - */ - protected function prepareBody(Message $message) - { - return $message->getBodyText(); - } - - /** - * Lazy load the connection - * - * @return Protocol\Smtp - */ - protected function lazyLoadConnection() - { - // Check if authentication is required and determine required class - $options = $this->getOptions(); - $config = $options->getConnectionConfig(); - $config['host'] = $options->getHost(); - $config['port'] = $options->getPort(); - - $this->setConnection($this->plugin($options->getConnectionClass(), $config)); - - return $this->connect(); - } - - /** - * Connect the connection, and pass it helo - * - * @return Protocol\Smtp - */ - protected function connect() - { - if (! $this->connection instanceof Protocol\Smtp) { - return $this->lazyLoadConnection(); - } - - $this->connection->connect(); - - $this->connectedTime = time(); - - $this->connection->helo($this->getOptions()->getName()); - - return $this->connection; - } -} diff --git a/lib/laminas/laminas-mail/src/Transport/SmtpOptions.php b/lib/laminas/laminas-mail/src/Transport/SmtpOptions.php deleted file mode 100644 index 599847064..000000000 --- a/lib/laminas/laminas-mail/src/Transport/SmtpOptions.php +++ /dev/null @@ -1,200 +0,0 @@ -name; - } - - /** - * Set the local client hostname or IP - * - * @todo hostname/IP validation - * @param string $name - * @throws InvalidArgumentException - * @return SmtpOptions - */ - public function setName($name) - { - if (! is_string($name) && $name !== null) { - throw new Exception\InvalidArgumentException(sprintf( - 'Name must be a string or null; argument of type "%s" provided', - is_object($name) ? $name::class : gettype($name) - )); - } - $this->name = $name; - return $this; - } - - /** - * Get connection class - * - * This should be either the class Laminas\Mail\Protocol\Smtp or a class - * extending it -- typically a class in the Laminas\Mail\Protocol\Smtp\Auth - * namespace. - * - * @return string - */ - public function getConnectionClass() - { - return $this->connectionClass; - } - - /** - * Set connection class - * - * @param string $connectionClass the value to be set - * @throws InvalidArgumentException - * @return SmtpOptions - */ - public function setConnectionClass($connectionClass) - { - if (! is_string($connectionClass) && $connectionClass !== null) { - throw new Exception\InvalidArgumentException(sprintf( - 'Connection class must be a string or null; argument of type "%s" provided', - is_object($connectionClass) ? $connectionClass::class : gettype($connectionClass) - )); - } - $this->connectionClass = $connectionClass; - return $this; - } - - /** - * Get connection configuration array - * - * @return array - */ - public function getConnectionConfig() - { - return $this->connectionConfig; - } - - /** - * Set connection configuration array - * - * @return SmtpOptions - */ - public function setConnectionConfig(array $connectionConfig) - { - $this->connectionConfig = $connectionConfig; - return $this; - } - - /** - * Get the host name - * - * @return string - */ - public function getHost() - { - return $this->host; - } - - /** - * Set the SMTP host - * - * @todo hostname/IP validation - * @param string $host - * @return SmtpOptions - */ - public function setHost($host) - { - $this->host = (string) $host; - return $this; - } - - /** - * Get the port the SMTP server runs on - * - * @return int - */ - public function getPort() - { - return $this->port; - } - - /** - * Set the port the SMTP server runs on - * - * @param int $port - * @throws InvalidArgumentException - * @return SmtpOptions - */ - public function setPort($port) - { - $port = (int) $port; - if ($port < 1) { - throw new Exception\InvalidArgumentException(sprintf( - 'Port must be greater than 1; received "%d"', - $port - )); - } - $this->port = $port; - return $this; - } - - /** - * @return int|null - */ - public function getConnectionTimeLimit() - { - return $this->connectionTimeLimit; - } - - /** - * @param int|null $seconds - * @return self - */ - public function setConnectionTimeLimit($seconds) - { - $this->connectionTimeLimit = $seconds === null - ? null - : (int) $seconds; - - return $this; - } -} diff --git a/lib/laminas/laminas-mail/src/Transport/TransportInterface.php b/lib/laminas/laminas-mail/src/Transport/TransportInterface.php deleted file mode 100644 index 7273d92a1..000000000 --- a/lib/laminas/laminas-mail/src/Transport/TransportInterface.php +++ /dev/null @@ -1,18 +0,0 @@ - ## 🇷🇺 Русским гражданам -> -> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм. -> -> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую. -> -> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!" -> -> ## 🇺🇸 To Citizens of Russia -> -> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism. -> -> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences. -> -> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!" - -> This package is considered feature-complete, and is now in **security-only** maintenance mode, following a [decision by the Technical Steering Committee](https://github.com/laminas/technical-steering-committee/blob/2b55453e172a1b8c9c4c212be7cf7e7a58b9352c/meetings/minutes/2020-08-03-TSC-Minutes.md#vote-on-components-to-mark-as-security-only). -> If you have a security issue, please [follow our security reporting guidelines](https://getlaminas.org/security/). -> If you wish to take on the role of maintainer, please [nominate yourself](https://github.com/laminas/technical-steering-committee/issues/new?assignees=&labels=Nomination&template=Maintainer_Nomination.md&title=%5BNOMINATION%5D%5BMAINTAINER%5D%3A+%7Bname+of+person+being+nominated%7D) -> -> If you are looking for an actively maintained package alternative, we recommend: -> -> - [symfony/mime](https://symfony.com/doc/current/components/mime.html) - -[![Build Status](https://github.com/laminas/laminas-mime/workflows/Continuous%20Integration/badge.svg)](https://github.com/laminas/laminas-mime/actions?query=workflow%3A"Continuous+Integration") - -`Laminas\Mime` is a support class for handling multipart MIME messages. -It is used by `Laminas\Mail` and `Laminas\Mime\Message` and may be used by applications requiring MIME support. - -## Installation - -Run the following to install this library: - -```bash -$ composer require laminas/laminas-mime -``` - -## Documentation - -Browse the documentation online at https://docs.laminas.dev/laminas-mime/ - -## Support - -- [Issues](https://github.com/laminas/laminas-mime/issues/) -- [Chat](https://laminas.dev/chat/) -- [Forum](https://discourse.laminas.dev/) diff --git a/lib/laminas/laminas-mime/composer.json b/lib/laminas/laminas-mime/composer.json deleted file mode 100644 index 76a631daa..000000000 --- a/lib/laminas/laminas-mime/composer.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "laminas/laminas-mime", - "description": "Create and parse MIME messages and parts", - "license": "BSD-3-Clause", - "keywords": [ - "laminas", - "mime" - ], - "homepage": "https://laminas.dev", - "support": { - "docs": "https://docs.laminas.dev/laminas-mime/", - "issues": "https://github.com/laminas/laminas-mime/issues", - "source": "https://github.com/laminas/laminas-mime", - "rss": "https://github.com/laminas/laminas-mime/releases.atom", - "chat": "https://laminas.dev/chat", - "forum": "https://discourse.laminas.dev" - }, - "config": { - "sort-packages": true, - "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true - } - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", - "laminas/laminas-stdlib": "^2.7 || ^3.0" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-mail": "^2.19.0", - "phpunit/phpunit": "~9.5.25" - }, - "suggest": { - "laminas/laminas-mail": "Laminas\\Mail component" - }, - "autoload": { - "psr-4": { - "Laminas\\Mime\\": "src/" - } - }, - "autoload-dev": { - "files": [ - "test/TestAsset/Mail/Headers.php" - ], - "psr-4": { - "LaminasTest\\Mime\\": "test/" - } - }, - "scripts": { - "check": [ - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" - }, - "conflict": { - "zendframework/zend-mime": "*" - } -} diff --git a/lib/laminas/laminas-mime/composer.lock b/lib/laminas/laminas-mime/composer.lock deleted file mode 100644 index 0a1ca5f50..000000000 --- a/lib/laminas/laminas-mime/composer.lock +++ /dev/null @@ -1,2902 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "0bb344763a1f69884ddce40e96a68855", - "packages": [ - { - "name": "laminas/laminas-stdlib", - "version": "3.15.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "63b66bd4b696f024f42616b9d95cdb10e5109c27" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/63b66bd4b696f024f42616b9d95cdb10e5109c27", - "reference": "63b66bd4b696f024f42616b9d95cdb10e5109c27", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-stdlib": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "phpbench/phpbench": "^1.2.6", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.28" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Stdlib\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "SPL extensions, array utilities, error handlers, and more", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "stdlib" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-stdlib/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-stdlib/issues", - "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", - "source": "https://github.com/laminas/laminas-stdlib" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-10T19:10:24+00:00" - } - ], - "packages-dev": [ - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2022-02-04T12:51:07+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "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" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "laminas/laminas-coding-standard", - "version": "2.4.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-coding-standard.git", - "reference": "eb076dd86aa93dd424856b150c9b6f76c1fdfabc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/eb076dd86aa93dd424856b150c9b6f76c1fdfabc", - "reference": "eb076dd86aa93dd424856b150c9b6f76c1fdfabc", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", - "php": "^7.4 || ^8.0", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.6", - "webimpress/coding-standard": "^1.2" - }, - "conflict": { - "phpstan/phpdoc-parser": ">=1.6.0" - }, - "type": "phpcodesniffer-standard", - "autoload": { - "psr-4": { - "LaminasCodingStandard\\": "src/LaminasCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Laminas Coding Standard", - "homepage": "https://laminas.dev", - "keywords": [ - "Coding Standard", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-coding-standard/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-coding-standard/issues", - "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", - "source": "https://github.com/laminas/laminas-coding-standard" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-08-24T17:45:47+00:00" - }, - { - "name": "laminas/laminas-loader", - "version": "2.9.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-loader.git", - "reference": "51ed9c3fa42d1098a9997571730c0cbf42d078d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/51ed9c3fa42d1098a9997571730c0cbf42d078d3", - "reference": "51ed9c3fa42d1098a9997571730c0cbf42d078d3", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-loader": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "~9.5.25" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Loader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Autoloading and plugin loading strategies", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "loader" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-loader/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-loader/issues", - "rss": "https://github.com/laminas/laminas-loader/releases.atom", - "source": "https://github.com/laminas/laminas-loader" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-16T12:50:49+00:00" - }, - { - "name": "laminas/laminas-mail", - "version": "2.19.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-mail.git", - "reference": "edf3832c05165775589af2fc698b5f9984d4c5f1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-mail/zipball/edf3832c05165775589af2fc698b5f9984d4c5f1", - "reference": "edf3832c05165775589af2fc698b5f9984d4c5f1", - "shasum": "" - }, - "require": { - "ext-iconv": "*", - "laminas/laminas-loader": "^2.8.0", - "laminas/laminas-mime": "^2.10.0", - "laminas/laminas-stdlib": "^3.11.0", - "laminas/laminas-validator": "^2.23.0", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "symfony/polyfill-intl-idn": "^1.26.0", - "symfony/polyfill-mbstring": "^1.16.0", - "webmozart/assert": "^1.11.0" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-crypt": "^3.8.0", - "laminas/laminas-db": "^2.15.0", - "laminas/laminas-servicemanager": "^3.19", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.17.0", - "symfony/process": "^6.0.11", - "vimeo/psalm": "^4.29" - }, - "suggest": { - "laminas/laminas-crypt": "^3.8 Crammd5 support in SMTP Auth", - "laminas/laminas-servicemanager": "^3.16 when using SMTP to deliver messages" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Mail", - "config-provider": "Laminas\\Mail\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Mail\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "mail" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-mail/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-mail/issues", - "rss": "https://github.com/laminas/laminas-mail/releases.atom", - "source": "https://github.com/laminas/laminas-mail" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-14T13:05:29+00:00" - }, - { - "name": "laminas/laminas-servicemanager", - "version": "3.19.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "ed160729bb8721127efdaac799f9a298963345b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/ed160729bb8721127efdaac799f9a298963345b1", - "reference": "ed160729bb8721127efdaac799f9a298963345b1", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.2.1", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "psr/container": "^1.0" - }, - "conflict": { - "ext-psr": "*", - "laminas/laminas-code": "<3.3.1", - "zendframework/zend-code": "<3.3.1", - "zendframework/zend-servicemanager": "*" - }, - "provide": { - "psr/container-implementation": "^1.0" - }, - "replace": { - "container-interop/container-interop": "^1.2.0" - }, - "require-dev": { - "composer/package-versions-deprecated": "^1.11.99.5", - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-container-config-test": "^0.7", - "laminas/laminas-dependency-plugin": "^2.2", - "mikey179/vfsstream": "^1.6.11@alpha", - "ocramius/proxy-manager": "^2.14.1", - "phpbench/phpbench": "^1.2.6", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.28" - }, - "suggest": { - "ocramius/proxy-manager": "ProxyManager ^2.1.1 to handle lazy initialization of services" - }, - "bin": [ - "bin/generate-deps-for-config-factory", - "bin/generate-factory-for-class" - ], - "type": "library", - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Laminas\\ServiceManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Factory-Driven Dependency Injection Container", - "homepage": "https://laminas.dev", - "keywords": [ - "PSR-11", - "dependency-injection", - "di", - "dic", - "laminas", - "service-manager", - "servicemanager" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-servicemanager/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-servicemanager/issues", - "rss": "https://github.com/laminas/laminas-servicemanager/releases.atom", - "source": "https://github.com/laminas/laminas-servicemanager" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-10T20:59:22+00:00" - }, - { - "name": "laminas/laminas-validator", - "version": "2.26.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-validator.git", - "reference": "a995b21d18c63cd1f5d123d0d2cd31a1c2d828dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/a995b21d18c63cd1f5d123d0d2cd31a1c2d828dc", - "reference": "a995b21d18c63cd1f5d123d0d2cd31a1c2d828dc", - "shasum": "" - }, - "require": { - "laminas/laminas-servicemanager": "^3.12.0", - "laminas/laminas-stdlib": "^3.13", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-validator": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "laminas/laminas-db": "^2.15.0", - "laminas/laminas-filter": "^2.22", - "laminas/laminas-http": "^2.16.0", - "laminas/laminas-i18n": "^2.19", - "laminas/laminas-session": "^2.13.0", - "laminas/laminas-uri": "^2.9.1", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.17.0", - "psr/http-client": "^1.0.1", - "psr/http-factory": "^1.0.1", - "psr/http-message": "^1.0.1", - "vimeo/psalm": "^4.28" - }, - "suggest": { - "laminas/laminas-db": "Laminas\\Db component, required by the (No)RecordExists validator", - "laminas/laminas-filter": "Laminas\\Filter component, required by the Digits validator", - "laminas/laminas-i18n": "Laminas\\I18n component to allow translation of validation error messages", - "laminas/laminas-i18n-resources": "Translations of validator messages", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", - "laminas/laminas-session": "Laminas\\Session component, ^2.8; required by the Csrf validator", - "laminas/laminas-uri": "Laminas\\Uri component, required by the Uri and Sitemap\\Loc validators", - "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Validator", - "config-provider": "Laminas\\Validator\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Validator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "validator" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-validator/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-validator/issues", - "rss": "https://github.com/laminas/laminas-validator/releases.atom", - "source": "https://github.com/laminas/laminas-validator" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-11T12:58:36+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "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" - }, - "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.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-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/v4.15.1" - }, - "time": "2022-09-04T07:30:47+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "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.3" - }, - "time": "2021-07-20T11:28:43+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": "phpstan/phpdoc-parser", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "981cc368a216c988e862a75e526b6076987d1b50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50", - "reference": "981cc368a216c988e862a75e526b6076987d1b50", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "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/1.5.1" - }, - "time": "2022-05-05T11:32:40+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.17", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "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" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.2-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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-08-30T12:24:04+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-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", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.25", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "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.13", - "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" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.5-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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.25" - }, - "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": "2022-09-25T03:44:45+00:00" - }, - { - "name": "psr/container", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "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/1.1.2" - }, - "time": "2021-11-05T16:50:12+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "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": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-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 types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "7.2.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phing/phing": "2.17.3", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.7.1", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2022-05-25T10:58:12+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "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": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0" - }, - "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": "2022-05-24T11:49:31+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "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" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" - }, - "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": "2022-05-24T11:49:31+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" - }, - "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": "2022-05-24T11:49:31+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" - }, - "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": "2022-05-24T11:49:31+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "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" - } - ], - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "webimpress/coding-standard", - "version": "1.2.4", - "source": { - "type": "git", - "url": "https://github.com/webimpress/coding-standard.git", - "reference": "cd0c4b0b97440c337c1f7da17b524674ca2f9ca9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/cd0c4b0b97440c337c1f7da17b524674ca2f9ca9", - "reference": "cd0c4b0b97440c337c1f7da17b524674ca2f9ca9", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.13" - }, - "type": "phpcodesniffer-standard", - "extra": { - "dev-master": "1.2.x-dev", - "dev-develop": "1.3.x-dev" - }, - "autoload": { - "psr-4": { - "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "description": "Webimpress Coding Standard", - "keywords": [ - "Coding Standard", - "PSR-2", - "phpcs", - "psr-12", - "webimpress" - ], - "support": { - "issues": "https://github.com/webimpress/coding-standard/issues", - "source": "https://github.com/webimpress/coding-standard/tree/1.2.4" - }, - "funding": [ - { - "url": "https://github.com/michalbundyra", - "type": "github" - } - ], - "time": "2022-02-15T19:52:12+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": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "platform-dev": [], - "plugin-api-version": "2.6.0" -} diff --git a/lib/laminas/laminas-mime/src/Decode.php b/lib/laminas/laminas-mime/src/Decode.php deleted file mode 100644 index 5afdeab2d..000000000 --- a/lib/laminas/laminas-mime/src/Decode.php +++ /dev/null @@ -1,240 +0,0 @@ - array(name => value), 'body' => content), null if no parts found - * @throws Exception\RuntimeException - */ - public static function splitMessageStruct($message, $boundary, $EOL = Mime::LINEEND) - { - $parts = static::splitMime($message, $boundary); - if (! $parts) { - return; - } - $result = []; - $headers = null; // "Declare" variable before the first usage "for reading" - $body = null; // "Declare" variable before the first usage "for reading" - foreach ($parts as $part) { - static::splitMessage($part, $headers, $body, $EOL); - $result[] = [ - 'header' => $headers, - 'body' => $body, - ]; - } - return $result; - } - - /** - * split a message in header and body part, if no header or an - * invalid header is found $headers is empty - * - * The charset of the returned headers depend on your iconv settings. - * - * @param string|Headers $message raw message with header and optional content - * @param Headers $headers output param, headers container - * @param string $body output param, content of message - * @param string $EOL EOL string; defaults to {@link Laminas\Mime\Mime::LINEEND} - * @param bool $strict enable strict mode for parsing message - * @return null - */ - public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LINEEND, $strict = false) - { - if ($message instanceof Headers) { - $message = $message->toString(); - } - // check for valid header at first line - $firstlinePos = strpos($message, "\n"); - $firstline = $firstlinePos === false ? $message : substr($message, 0, $firstlinePos); - if (! preg_match('%^[^\s]+[^:]*:%', $firstline)) { - $headers = new Headers(); - // TODO: we're ignoring \r for now - is this function fast enough and is it safe to assume noone needs \r? - $body = str_replace(["\r", "\n"], ['', $EOL], $message); - return; - } - - // see @Laminas-372, pops the first line off a message if it doesn't contain a header - if (! $strict) { - $parts = explode(':', $firstline, 2); - if (count($parts) !== 2) { - $message = substr($message, strpos($message, $EOL) + 1); - } - } - - // @todo splitMime removes "\r" sequences, which breaks valid mime - // messages as returned by many mail servers - $headersEOL = $EOL; - - // find an empty line between headers and body - // default is set new line - // @todo Maybe this is too much "magic"; we should be more strict here - if (strpos($message, $EOL . $EOL)) { - [$headers, $body] = explode($EOL . $EOL, $message, 2); - // next is the standard new line - } elseif ($EOL !== "\r\n" && strpos($message, "\r\n\r\n")) { - [$headers, $body] = explode("\r\n\r\n", $message, 2); - $headersEOL = "\r\n"; // Headers::fromString will fail with incorrect EOL - // next is the other "standard" new line - } elseif ($EOL !== "\n" && strpos($message, "\n\n")) { - [$headers, $body] = explode("\n\n", $message, 2); - $headersEOL = "\n"; - // at last resort find anything that looks like a new line - } else { - ErrorHandler::start(E_NOTICE | E_WARNING); - [$headers, $body] = preg_split("%([\r\n]+)\\1%U", $message, 2); - ErrorHandler::stop(); - } - - $headers = Headers::fromString($headers, $headersEOL); - } - - /** - * split a content type in its different parts - * - * @param string $type content-type - * @param string $wantedPart the wanted part, else an array with all parts is returned - * @return string|array wanted part or all parts as array('type' => content-type, partname => value) - */ - public static function splitContentType($type, $wantedPart = null) - { - return static::splitHeaderField($type, $wantedPart, 'type'); - } - - /** - * split a header field like content type in its different parts - * - * @param string $field header field - * @param string $wantedPart the wanted part, else an array with all parts is returned - * @param string $firstName key name for the first part - * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value) - * @throws Exception\RuntimeException - */ - public static function splitHeaderField($field, $wantedPart = null, $firstName = '0') - { - $wantedPart = strtolower($wantedPart ?? ''); - $firstName = strtolower($firstName); - - // special case - a bit optimized - if ($firstName === $wantedPart) { - $field = strtok($field, ';'); - return $field[0] === '"' ? substr($field, 1, -1) : $field; - } - - $field = $firstName . '=' . $field; - if (! preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) { - throw new Exception\RuntimeException('not a valid header field'); - } - - if ($wantedPart) { - foreach ($matches[1] as $key => $name) { - if (strcasecmp($name, $wantedPart)) { - continue; - } - if ($matches[2][$key][0] !== '"') { - return $matches[2][$key]; - } - return substr($matches[2][$key], 1, -1); - } - return; - } - - $split = []; - foreach ($matches[1] as $key => $name) { - $name = strtolower($name); - if ($matches[2][$key][0] === '"') { - $split[$name] = substr($matches[2][$key], 1, -1); - } else { - $split[$name] = $matches[2][$key]; - } - } - - return $split; - } - - /** - * decode a quoted printable encoded string - * - * The charset of the returned string depends on your iconv settings. - * - * @param string $string encoded string - * @return string decoded string - */ - public static function decodeQuotedPrintable($string) - { - return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); - } -} diff --git a/lib/laminas/laminas-mime/src/Exception/ExceptionInterface.php b/lib/laminas/laminas-mime/src/Exception/ExceptionInterface.php deleted file mode 100644 index 762e2c007..000000000 --- a/lib/laminas/laminas-mime/src/Exception/ExceptionInterface.php +++ /dev/null @@ -1,7 +0,0 @@ -parts; - } - - /** - * Sets the given array of Laminas\Mime\Part as the array for the message - * - * @param array $parts - * @return self - */ - public function setParts($parts) - { - $this->parts = $parts; - return $this; - } - - /** - * Append a new Laminas\Mime\Part to the current message - * - * @throws Exception\InvalidArgumentException - * @return self - */ - public function addPart(Part $part) - { - foreach ($this->getParts() as $row) { - if ($part === $row) { - throw new Exception\InvalidArgumentException(sprintf( - 'Provided part %s already defined.', - $part->getId() - )); - } - } - - $this->parts[] = $part; - return $this; - } - - /** - * Check if message needs to be sent as multipart - * MIME message or if it has only one part. - * - * @return bool - */ - public function isMultiPart() - { - return count($this->parts) > 1; - } - - /** - * Set Laminas\Mime\Mime object for the message - * - * This can be used to set the boundary specifically or to use a subclass of - * Laminas\Mime for generating the boundary. - * - * @return self - */ - public function setMime(Mime $mime) - { - $this->mime = $mime; - return $this; - } - - /** - * Returns the Laminas\Mime\Mime object in use by the message - * - * If the object was not present, it is created and returned. Can be used to - * determine the boundary used in this message. - * - * @return Mime - */ - public function getMime() - { - if ($this->mime === null) { - $this->mime = new Mime(); - } - - return $this->mime; - } - - /** - * Generate MIME-compliant message from the current configuration - * - * This can be a multipart message if more than one MIME part was added. If - * only one part is present, the content of this part is returned. If no - * part had been added, an empty string is returned. - * - * Parts are separated by the mime boundary as defined in Laminas\Mime\Mime. If - * {@link setMime()} has been called before this method, the Laminas\Mime\Mime - * object set by this call will be used. Otherwise, a new Laminas\Mime\Mime object - * is generated and used. - * - * @param string $EOL EOL string; defaults to {@link Laminas\Mime\Mime::LINEEND} - * @return string - */ - public function generateMessage($EOL = Mime::LINEEND) - { - if (! $this->isMultiPart()) { - if (empty($this->parts)) { - return ''; - } - $part = current($this->parts); - $body = $part->getContent($EOL); - } else { - $mime = $this->getMime(); - - $boundaryLine = $mime->boundaryLine($EOL); - $body = 'This is a message in Mime Format. If you see this, ' - . "your mail reader does not support this format." . $EOL; - - foreach (array_keys($this->parts) as $p) { - $body .= $boundaryLine - . $this->getPartHeaders($p, $EOL) - . $EOL - . $this->getPartContent($p, $EOL); - } - - $body .= $mime->mimeEnd($EOL); - } - - return trim($body); - } - - /** - * Get the headers of a given part as an array - * - * @param int $partnum - * @return array - */ - public function getPartHeadersArray($partnum) - { - return $this->parts[$partnum]->getHeadersArray(); - } - - /** - * Get the headers of a given part as a string - * - * @param int $partnum - * @param string $EOL - * @return string - */ - public function getPartHeaders($partnum, $EOL = Mime::LINEEND) - { - return $this->parts[$partnum]->getHeaders($EOL); - } - - /** - * Get the (encoded) content of a given part as a string - * - * @param int $partnum - * @param string $EOL - * @return string - */ - public function getPartContent($partnum, $EOL = Mime::LINEEND) - { - return $this->parts[$partnum]->getContent($EOL); - } - - /** - * Explode MIME multipart string into separate parts - * - * Parts consist of the header and the body of each MIME part. - * - * @param string $body - * @param string $boundary - * @throws Exception\RuntimeException - * @return array - */ - protected static function _disassembleMime($body, $boundary) - { - $start = 0; - $res = []; - // find every mime part limiter and cut out the - // string before it. - // the part before the first boundary string is discarded: - $p = strpos($body, '--' . $boundary . "\n", $start); - if ($p === false) { - // no parts found! - return []; - } - - // position after first boundary line - $start = $p + 3 + strlen($boundary); - - while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) { - $res[] = substr($body, $start, $p - $start); - $start = $p + 3 + strlen($boundary); - } - - // no more parts, find end boundary - $p = strpos($body, '--' . $boundary . '--', $start); - if ($p === false) { - throw new Exception\RuntimeException('Not a valid Mime Message: End Missing'); - } - - // the remaining part also needs to be parsed: - $res[] = substr($body, $start, $p - $start); - return $res; - } - - /** - * Decodes a MIME encoded string and returns a Laminas\Mime\Message object with - * all the MIME parts set according to the given string - * - * @param string $message - * @param string $boundary Multipart boundary; if omitted, $message will be - * treated as a single part. - * @param string $EOL EOL string; defaults to {@link Laminas\Mime\Mime::LINEEND} - * @throws Exception\RuntimeException - * @return Message - */ - public static function createFromMessage($message, $boundary = null, $EOL = Mime::LINEEND) - { - if ($boundary) { - $parts = Decode::splitMessageStruct($message, $boundary, $EOL); - } else { - Decode::splitMessage($message, $headers, $body, $EOL); - $parts = [ - [ - 'header' => $headers, - 'body' => $body, - ], - ]; - } - - $res = new static(); - foreach ($parts as $part) { - // now we build a new MimePart for the current Message Part: - $properties = []; - foreach ($part['header'] as $header) { - /** @var HeaderInterface $header */ - /** - * @todo check for characterset and filename - */ - - $fieldName = $header->getFieldName(); - $fieldValue = $header->getFieldValue(); - switch (strtolower($fieldName)) { - case 'content-type': - $properties['type'] = $fieldValue; - break; - case 'content-transfer-encoding': - $properties['encoding'] = $fieldValue; - break; - case 'content-id': - $properties['id'] = trim($fieldValue, '<>'); - break; - case 'content-disposition': - $properties['disposition'] = $fieldValue; - break; - case 'content-description': - $properties['description'] = $fieldValue; - break; - case 'content-location': - $properties['location'] = $fieldValue; - break; - case 'content-language': - $properties['language'] = $fieldValue; - break; - default: - // Ignore unknown header - break; - } - } - - $body = $part['body']; - - if (isset($properties['encoding'])) { - switch ($properties['encoding']) { - case 'quoted-printable': - $body = quoted_printable_decode($body); - break; - case 'base64': - $body = base64_decode($body); - break; - } - } - - $newPart = new Part($body); - foreach ($properties as $key => $value) { - $newPart->$key = $value; - } - $res->addPart($newPart); - } - - return $res; - } -} diff --git a/lib/laminas/laminas-mime/src/Mime.php b/lib/laminas/laminas-mime/src/Mime.php deleted file mode 100644 index 14f5ccee4..000000000 --- a/lib/laminas/laminas-mime/src/Mime.php +++ /dev/null @@ -1,721 +0,0 @@ -[\x21\x23-\x26\x2a\x2b\x2d\x5e\5f\60\x7b-\x7ea-zA-Z0-9]+)\?(?P[\x21\x23-\x26\x2a\x2b\x2d\x5e\5f\60\x7b-\x7ea-zA-Z0-9]+)\?(?P[\x21-\x3e\x40-\x7e]+)#'; - // phpcs:enable - - /** @var null|string */ - protected $boundary; - - /** @var int */ - protected static $makeUnique = 0; - - /** - * Lookup-tables for QuotedPrintable - * - * @var string[] - */ - public static $qpKeys = [ - "\x00", - "\x01", - "\x02", - "\x03", - "\x04", - "\x05", - "\x06", - "\x07", - "\x08", - "\x09", - "\x0A", - "\x0B", - "\x0C", - "\x0D", - "\x0E", - "\x0F", - "\x10", - "\x11", - "\x12", - "\x13", - "\x14", - "\x15", - "\x16", - "\x17", - "\x18", - "\x19", - "\x1A", - "\x1B", - "\x1C", - "\x1D", - "\x1E", - "\x1F", - "\x7F", - "\x80", - "\x81", - "\x82", - "\x83", - "\x84", - "\x85", - "\x86", - "\x87", - "\x88", - "\x89", - "\x8A", - "\x8B", - "\x8C", - "\x8D", - "\x8E", - "\x8F", - "\x90", - "\x91", - "\x92", - "\x93", - "\x94", - "\x95", - "\x96", - "\x97", - "\x98", - "\x99", - "\x9A", - "\x9B", - "\x9C", - "\x9D", - "\x9E", - "\x9F", - "\xA0", - "\xA1", - "\xA2", - "\xA3", - "\xA4", - "\xA5", - "\xA6", - "\xA7", - "\xA8", - "\xA9", - "\xAA", - "\xAB", - "\xAC", - "\xAD", - "\xAE", - "\xAF", - "\xB0", - "\xB1", - "\xB2", - "\xB3", - "\xB4", - "\xB5", - "\xB6", - "\xB7", - "\xB8", - "\xB9", - "\xBA", - "\xBB", - "\xBC", - "\xBD", - "\xBE", - "\xBF", - "\xC0", - "\xC1", - "\xC2", - "\xC3", - "\xC4", - "\xC5", - "\xC6", - "\xC7", - "\xC8", - "\xC9", - "\xCA", - "\xCB", - "\xCC", - "\xCD", - "\xCE", - "\xCF", - "\xD0", - "\xD1", - "\xD2", - "\xD3", - "\xD4", - "\xD5", - "\xD6", - "\xD7", - "\xD8", - "\xD9", - "\xDA", - "\xDB", - "\xDC", - "\xDD", - "\xDE", - "\xDF", - "\xE0", - "\xE1", - "\xE2", - "\xE3", - "\xE4", - "\xE5", - "\xE6", - "\xE7", - "\xE8", - "\xE9", - "\xEA", - "\xEB", - "\xEC", - "\xED", - "\xEE", - "\xEF", - "\xF0", - "\xF1", - "\xF2", - "\xF3", - "\xF4", - "\xF5", - "\xF6", - "\xF7", - "\xF8", - "\xF9", - "\xFA", - "\xFB", - "\xFC", - "\xFD", - "\xFE", - "\xFF", - ]; - - /** @var string[] */ - public static $qpReplaceValues = [ - "=00", - "=01", - "=02", - "=03", - "=04", - "=05", - "=06", - "=07", - "=08", - "=09", - "=0A", - "=0B", - "=0C", - "=0D", - "=0E", - "=0F", - "=10", - "=11", - "=12", - "=13", - "=14", - "=15", - "=16", - "=17", - "=18", - "=19", - "=1A", - "=1B", - "=1C", - "=1D", - "=1E", - "=1F", - "=7F", - "=80", - "=81", - "=82", - "=83", - "=84", - "=85", - "=86", - "=87", - "=88", - "=89", - "=8A", - "=8B", - "=8C", - "=8D", - "=8E", - "=8F", - "=90", - "=91", - "=92", - "=93", - "=94", - "=95", - "=96", - "=97", - "=98", - "=99", - "=9A", - "=9B", - "=9C", - "=9D", - "=9E", - "=9F", - "=A0", - "=A1", - "=A2", - "=A3", - "=A4", - "=A5", - "=A6", - "=A7", - "=A8", - "=A9", - "=AA", - "=AB", - "=AC", - "=AD", - "=AE", - "=AF", - "=B0", - "=B1", - "=B2", - "=B3", - "=B4", - "=B5", - "=B6", - "=B7", - "=B8", - "=B9", - "=BA", - "=BB", - "=BC", - "=BD", - "=BE", - "=BF", - "=C0", - "=C1", - "=C2", - "=C3", - "=C4", - "=C5", - "=C6", - "=C7", - "=C8", - "=C9", - "=CA", - "=CB", - "=CC", - "=CD", - "=CE", - "=CF", - "=D0", - "=D1", - "=D2", - "=D3", - "=D4", - "=D5", - "=D6", - "=D7", - "=D8", - "=D9", - "=DA", - "=DB", - "=DC", - "=DD", - "=DE", - "=DF", - "=E0", - "=E1", - "=E2", - "=E3", - "=E4", - "=E5", - "=E6", - "=E7", - "=E8", - "=E9", - "=EA", - "=EB", - "=EC", - "=ED", - "=EE", - "=EF", - "=F0", - "=F1", - "=F2", - "=F3", - "=F4", - "=F5", - "=F6", - "=F7", - "=F8", - "=F9", - "=FA", - "=FB", - "=FC", - "=FD", - "=FE", - "=FF", - ]; - // @codingStandardsIgnoreStart - public static $qpKeysString = - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"; - // @codingStandardsIgnoreEnd - - /** - * Check if the given string is "printable" - * - * Checks that a string contains no unprintable characters. If this returns - * false, encode the string for secure delivery. - * - * @param string $str - * @return bool - */ - public static function isPrintable($str) - { - return strcspn($str, static::$qpKeysString) === strlen($str); - } - - /** - * Encode a given string with the QUOTED_PRINTABLE mechanism and wrap the lines. - * - * @param string $str - * @param int $lineLength Defaults to {@link LINELENGTH} - * @param string $lineEnd Defaults to {@link LINEEND} - * @return string - */ - public static function encodeQuotedPrintable( - $str, - $lineLength = self::LINELENGTH, - $lineEnd = self::LINEEND - ) { - $out = ''; - $str = self::_encodeQuotedPrintable($str); - - // Split encoded text into separate lines - $initialPtr = 0; - $strLength = strlen($str); - while ($initialPtr < $strLength) { - $continueAt = $strLength - $initialPtr; - - if ($continueAt > $lineLength) { - $continueAt = $lineLength; - } - - $chunk = substr($str, $initialPtr, $continueAt); - - // Ensure we are not splitting across an encoded character - $endingMarkerPos = strrpos($chunk, '='); - if ($endingMarkerPos !== false && $endingMarkerPos >= strlen($chunk) - 2) { - $chunk = substr($chunk, 0, $endingMarkerPos); - $continueAt = $endingMarkerPos; - } - - if (ord($chunk[0]) === 0x2E) { // 0x2E is a dot - $chunk = '=2E' . substr($chunk, 1); - } - - // copied from swiftmailer https://git.io/vAXU1 - switch (ord(substr($chunk, strlen($chunk) - 1))) { - case 0x09: // Horizontal Tab - $chunk = substr_replace($chunk, '=09', strlen($chunk) - 1, 1); - break; - case 0x20: // Space - $chunk = substr_replace($chunk, '=20', strlen($chunk) - 1, 1); - break; - } - - // Add string and continue - $out .= $chunk . '=' . $lineEnd; - $initialPtr += $continueAt; - } - - $out = rtrim($out, $lineEnd); - $out = rtrim($out, '='); - return $out; - } - - /** - * Converts a string into quoted printable format. - * - * @param string $str - * @return string - */ - // @codingStandardsIgnoreStart - private static function _encodeQuotedPrintable($str) - { - // @codingStandardsIgnoreEnd - $str = str_replace('=', '=3D', $str); - $str = str_replace(static::$qpKeys, static::$qpReplaceValues, $str); - $str = rtrim($str); - return $str; - } - - /** - * Encode a given string with the QUOTED_PRINTABLE mechanism for Mail Headers. - * - * Mail headers depend on an extended quoted printable algorithm otherwise - * a range of bugs can occur. - * - * @param string $str - * @param string $charset - * @param int $lineLength Defaults to {@link LINELENGTH} - * @param string $lineEnd Defaults to {@link LINEEND} - * @param positive-int|0 $headerNameSize When folding a line, it is necessary to calculate - * the length of the entire line (together with the header name). - * Therefore, you can specify the header name and colon length - * in this argument to fold the string properly. - * @return string - */ - public static function encodeQuotedPrintableHeader( - $str, - $charset, - $lineLength = self::LINELENGTH, - $lineEnd = self::LINEEND, - $headerNameSize = 0 - ) { - // Reduce line-length by the length of the required delimiter, charsets and encoding - $prefix = sprintf('=?%s?Q?', $charset); - $lineLength = $lineLength - strlen($prefix) - 3; - - $str = self::_encodeQuotedPrintable($str); - - // Mail-Header required chars have to be encoded also: - $str = str_replace(['?', ',', ' ', '_'], ['=3F', '=2C', '=20', '=5F'], $str); - - // initialize first line, we need it anyways - $lines = [0 => '']; - - // Split encoded text into separate lines - $tmp = ''; - while (strlen($str) > 0) { - $currentLine = max(count($lines) - 1, 0); - $token = static::getNextQuotedPrintableToken($str); - $substr = substr($str, strlen($token)); - $str = false === $substr ? '' : $substr; - - $tmp .= $token; - if ($token === '=20') { - // only if we have a single char token or space, we can append the - // tempstring it to the current line or start a new line if necessary. - if ($currentLine === 0) { - // The size of the first line should be calculated with the header name. - $currentLineLength = strlen($lines[$currentLine] . $tmp) + $headerNameSize; - } else { - $currentLineLength = strlen($lines[$currentLine] . $tmp); - } - - $lineLimitReached = $currentLineLength > $lineLength; - $noCurrentLine = $lines[$currentLine] === ''; - if ($noCurrentLine && $lineLimitReached) { - $lines[$currentLine] = $tmp; - $lines[$currentLine + 1] = ''; - } elseif ($lineLimitReached) { - $lines[$currentLine + 1] = $tmp; - } else { - $lines[$currentLine] .= $tmp; - } - $tmp = ''; - } - // don't forget to append the rest to the last line - if (strlen($str) === 0) { - $lines[$currentLine] .= $tmp; - } - } - - // assemble the lines together by pre- and appending delimiters, charset, encoding. - for ($i = 0, $count = count($lines); $i < $count; $i++) { - $lines[$i] = " " . $prefix . $lines[$i] . "?="; - } - $str = trim(implode($lineEnd, $lines)); - return $str; - } - - /** - * Retrieves the first token from a quoted printable string. - * - * @param string $str - * @return string - */ - private static function getNextQuotedPrintableToken($str) - { - if (0 === strpos($str, '=')) { - $token = substr($str, 0, 3); - } else { - $token = substr($str, 0, 1); - } - return $token; - } - - /** - * Encode a given string in mail header compatible base64 encoding. - * - * @param string $str - * @param string $charset - * @param int $lineLength Defaults to {@link LINELENGTH} - * @param string $lineEnd Defaults to {@link LINEEND} - * @return string - */ - public static function encodeBase64Header( - $str, - $charset, - $lineLength = self::LINELENGTH, - $lineEnd = self::LINEEND - ) { - $prefix = '=?' . $charset . '?B?'; - $suffix = '?='; - $remainingLength = $lineLength - strlen($prefix) - strlen($suffix); - - $encodedValue = static::encodeBase64($str, $remainingLength, $lineEnd); - $encodedValue = str_replace($lineEnd, $suffix . $lineEnd . ' ' . $prefix, $encodedValue); - $encodedValue = $prefix . $encodedValue . $suffix; - return $encodedValue; - } - - /** - * Encode a given string in base64 encoding and break lines - * according to the maximum linelength. - * - * @param string $str - * @param int $lineLength Defaults to {@link LINELENGTH} - * @param string $lineEnd Defaults to {@link LINEEND} - * @return string - */ - public static function encodeBase64( - $str, - $lineLength = self::LINELENGTH, - $lineEnd = self::LINEEND - ) { - $lineLength = $lineLength - ($lineLength % 4); - return rtrim(chunk_split(base64_encode($str), $lineLength, $lineEnd)); - } - - /** - * Constructor - * - * @param null|string $boundary - * @access public - */ - public function __construct($boundary = null) - { - // This string needs to be somewhat unique - if ($boundary === null) { - $this->boundary = '=_' . md5(microtime(1) . static::$makeUnique++); - } else { - $this->boundary = $boundary; - } - } - - // phpcs:disable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps - - /** - * Encode the given string with the given encoding. - * - * @param string $str - * @param string $encoding - * @param string $EOL EOL string; defaults to {@link LINEEND} - * @return string - */ - public static function encode($str, $encoding, $EOL = self::LINEEND) - { - switch ($encoding) { - case self::ENCODING_BASE64: - return static::encodeBase64($str, self::LINELENGTH, $EOL); - - case self::ENCODING_QUOTEDPRINTABLE: - return static::encodeQuotedPrintable($str, self::LINELENGTH, $EOL); - - default: - /** - * @todo 7Bit and 8Bit is currently handled the same way. - */ - return $str; - } - } - - /** - * Return a MIME boundary - * - * @access public - * @return string - */ - public function boundary() - { - return $this->boundary; - } - - /** - * Return a MIME boundary line - * - * @param string $EOL Defaults to {@link LINEEND} - * @access public - * @return string - */ - public function boundaryLine($EOL = self::LINEEND) - { - return $EOL . '--' . $this->boundary . $EOL; - } - - /** - * Return MIME ending - * - * @param string $EOL Defaults to {@link LINEEND} - * @access public - * @return string - */ - public function mimeEnd($EOL = self::LINEEND) - { - return $EOL . '--' . $this->boundary . '--' . $EOL; - } - - /** - * Detect MIME charset - * - * Extract parts according to https://tools.ietf.org/html/rfc2047#section-2 - * - * @param string $str - * @return string - */ - public static function mimeDetectCharset($str) - { - if (preg_match(self::CHARSET_REGEX, $str, $matches)) { - return strtoupper($matches['charset']); - } - - return 'ASCII'; - } -} diff --git a/lib/laminas/laminas-mime/src/Part.php b/lib/laminas/laminas-mime/src/Part.php deleted file mode 100644 index 20f77fd91..000000000 --- a/lib/laminas/laminas-mime/src/Part.php +++ /dev/null @@ -1,548 +0,0 @@ - */ - protected $filters = []; - - /** - * create a new Mime Part. - * The (unencoded) content of the Part as passed - * as a string or stream - * - * @param mixed $content String or Stream containing the content - * @throws Exception\InvalidArgumentException - */ - public function __construct($content = '') - { - $this->setContent($content); - } - - /** - * @todo error checking for setting $type - * @todo error checking for setting $encoding - */ - - /** - * Set type - * - * @param string $type - * @return self - */ - public function setType($type = Mime::TYPE_OCTETSTREAM) - { - $this->type = $type; - return $this; - } - - /** - * Get type - * - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * Set encoding - * - * @param string $encoding - * @return self - */ - public function setEncoding($encoding = Mime::ENCODING_8BIT) - { - $this->encoding = $encoding; - return $this; - } - - /** - * Get encoding - * - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Set id - * - * @param string $id - * @return self - */ - public function setId($id) - { - $this->id = $id; - return $this; - } - - /** - * Get id - * - * @return string - */ - public function getId() - { - return $this->id; - } - - /** - * Set disposition - * - * @param string $disposition - * @return self - */ - public function setDisposition($disposition) - { - $this->disposition = $disposition; - return $this; - } - - /** - * Get disposition - * - * @return string - */ - public function getDisposition() - { - return $this->disposition; - } - - /** - * Set description - * - * @param string $description - * @return self - */ - public function setDescription($description) - { - $this->description = $description; - return $this; - } - - /** - * Get description - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Set filename - * - * @param string $fileName - * @return self - */ - public function setFileName($fileName) - { - $this->filename = $fileName; - return $this; - } - - /** - * Get filename - * - * @return string - */ - public function getFileName() - { - return $this->filename; - } - - /** - * Set charset - * - * @param string $charset - * @return self - */ - public function setCharset($charset) - { - $this->charset = $charset; - return $this; - } - - /** - * Get charset - * - * @return string - */ - public function getCharset() - { - return $this->charset; - } - - /** - * Set boundary - * - * @param string $boundary - * @return self - */ - public function setBoundary($boundary) - { - $this->boundary = $boundary; - return $this; - } - - /** - * Get boundary - * - * @return string - */ - public function getBoundary() - { - return $this->boundary; - } - - /** - * Set location - * - * @param string $location - * @return self - */ - public function setLocation($location) - { - $this->location = $location; - return $this; - } - - /** - * Get location - * - * @return string - */ - public function getLocation() - { - return $this->location; - } - - /** - * Set language - * - * @param string $language - * @return self - */ - public function setLanguage($language) - { - $this->language = $language; - return $this; - } - - /** - * Get language - * - * @return string - */ - public function getLanguage() - { - return $this->language; - } - - /** - * Set content - * - * @param mixed $content String or Stream containing the content - * @throws Exception\InvalidArgumentException - * @return self - */ - public function setContent($content) - { - if (! is_string($content) && ! is_resource($content)) { - throw new Exception\InvalidArgumentException(sprintf( - 'Content must be string or resource; received "%s"', - is_object($content) ? $content::class : gettype($content) - )); - } - $this->content = $content; - if (is_resource($content)) { - $this->isStream = true; - } - - return $this; - } - - /** - * Set isStream - * - * @param bool $isStream - * @return self - */ - public function setIsStream($isStream = false) - { - $this->isStream = (bool) $isStream; - return $this; - } - - /** - * Get isStream - * - * @return bool - */ - public function getIsStream() - { - return $this->isStream; - } - - /** - * Set filters - * - * @param array $filters - * @return self - */ - public function setFilters($filters = []) - { - $this->filters = $filters; - return $this; - } - - /** - * Get Filters - * - * @return array - */ - public function getFilters() - { - return $this->filters; - } - - /** - * check if this part can be read as a stream. - * if true, getEncodedStream can be called, otherwise - * only getContent can be used to fetch the encoded - * content of the part - * - * @return bool - */ - public function isStream() - { - return $this->isStream; - } - - // phpcs:disable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps - - /** - * if this was created with a stream, return a filtered stream for - * reading the content. very useful for large file attachments. - * - * @param string $EOL - * @return resource - * @throws Exception\RuntimeException If not a stream or unable to append filter. - */ - public function getEncodedStream($EOL = Mime::LINEEND) - { - if (! $this->isStream) { - throw new Exception\RuntimeException('Attempt to get a stream from a string part'); - } - - //stream_filter_remove(); // ??? is that right? - switch ($this->encoding) { - case Mime::ENCODING_QUOTEDPRINTABLE: - if (array_key_exists(Mime::ENCODING_QUOTEDPRINTABLE, $this->filters)) { - stream_filter_remove($this->filters[Mime::ENCODING_QUOTEDPRINTABLE]); - } - $filter = stream_filter_append( - $this->content, - 'convert.quoted-printable-encode', - STREAM_FILTER_READ, - [ - 'line-length' => 76, - 'line-break-chars' => $EOL, - ] - ); - $this->filters[Mime::ENCODING_QUOTEDPRINTABLE] = $filter; - if (! is_resource($filter)) { - throw new Exception\RuntimeException('Failed to append quoted-printable filter'); - } - break; - case Mime::ENCODING_BASE64: - if (array_key_exists(Mime::ENCODING_BASE64, $this->filters)) { - stream_filter_remove($this->filters[Mime::ENCODING_BASE64]); - } - $filter = stream_filter_append( - $this->content, - 'convert.base64-encode', - STREAM_FILTER_READ, - [ - 'line-length' => 76, - 'line-break-chars' => $EOL, - ] - ); - $this->filters[Mime::ENCODING_BASE64] = $filter; - if (! is_resource($filter)) { - throw new Exception\RuntimeException('Failed to append base64 filter'); - } - break; - default: - } - return $this->content; - } - - /** - * Get the Content of the current Mime Part in the given encoding. - * - * @param string $EOL - * @return string - */ - public function getContent($EOL = Mime::LINEEND) - { - if ($this->isStream) { - $encodedStream = $this->getEncodedStream($EOL); - $encodedStreamContents = stream_get_contents($encodedStream); - $streamMetaData = stream_get_meta_data($encodedStream); - - if (isset($streamMetaData['seekable']) && $streamMetaData['seekable']) { - rewind($encodedStream); - } - - return $encodedStreamContents; - } - return Mime::encode($this->content, $this->encoding, $EOL); - } - - /** - * Get the RAW unencoded content from this part - * - * @return string - */ - public function getRawContent() - { - if ($this->isStream) { - return stream_get_contents($this->content); - } - return $this->content; - } - - /** - * Create and return the array of headers for this MIME part - * - * @access public - * @param string $EOL - * @return array - */ - public function getHeadersArray($EOL = Mime::LINEEND) - { - $headers = []; - - $contentType = $this->type; - if ($this->charset) { - $contentType .= '; charset=' . $this->charset; - } - - if ($this->boundary) { - $contentType .= ';' . $EOL - . " boundary=\"" . $this->boundary . '"'; - } - - $headers[] = ['Content-Type', $contentType]; - - if ($this->encoding) { - $headers[] = ['Content-Transfer-Encoding', $this->encoding]; - } - - if ($this->id) { - $headers[] = ['Content-ID', '<' . $this->id . '>']; - } - - if ($this->disposition) { - $disposition = $this->disposition; - if ($this->filename) { - $disposition .= '; filename="' . $this->filename . '"'; - } - $headers[] = ['Content-Disposition', $disposition]; - } - - if ($this->description) { - $headers[] = ['Content-Description', $this->description]; - } - - if ($this->location) { - $headers[] = ['Content-Location', $this->location]; - } - - if ($this->language) { - $headers[] = ['Content-Language', $this->language]; - } - - return $headers; - } - - /** - * Return the headers for this part as a string - * - * @param string $EOL - * @return String - */ - public function getHeaders($EOL = Mime::LINEEND) - { - $res = ''; - foreach ($this->getHeadersArray($EOL) as $header) { - $res .= $header[0] . ': ' . $header[1] . $EOL; - } - - return $res; - } -} diff --git a/lib/laminas/laminas-servicemanager/COPYRIGHT.md b/lib/laminas/laminas-servicemanager/COPYRIGHT.md deleted file mode 100644 index 0a8cccc06..000000000 --- a/lib/laminas/laminas-servicemanager/COPYRIGHT.md +++ /dev/null @@ -1 +0,0 @@ -Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) diff --git a/lib/laminas/laminas-servicemanager/LICENSE.md b/lib/laminas/laminas-servicemanager/LICENSE.md deleted file mode 100644 index 10b40f142..000000000 --- a/lib/laminas/laminas-servicemanager/LICENSE.md +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -- Neither the name of Laminas Foundation nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/laminas/laminas-servicemanager/README.md b/lib/laminas/laminas-servicemanager/README.md deleted file mode 100644 index 862c83f0a..000000000 --- a/lib/laminas/laminas-servicemanager/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# laminas-servicemanager - -[![Build Status](https://github.com/laminas/laminas-servicemanager/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/laminas/laminas-servicemanager/actions/workflows/continuous-integration.yml) -[![Psalm coverage](https://shepherd.dev/github/laminas/laminas-servicemanager/coverage.svg?)](https://shepherd.dev/github/laminas/laminas-servicemanager) - -> ## 🇷🇺 Русским гражданам -> -> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм. -> -> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую. -> -> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!" -> -> ## 🇺🇸 To Citizens of Russia -> -> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism. -> -> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences. -> -> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!" - -The Service Locator design pattern is implemented by the `Laminas\ServiceManager` -component. The Service Locator is a service/object locator, tasked with -retrieving other objects. - -- File issues at https://github.com/laminas/laminas-servicemanager/issues -- [Online documentation](https://docs.laminas.dev/laminas-servicemanager) -- [Documentation source files](docs/book/) - -## Benchmarks - -We provide scripts for benchmarking laminas-servicemanager using the -[PHPBench](https://github.com/phpbench/phpbench) framework; these can be -found in the `benchmarks/` directory. - -To execute the benchmarks you can run the following command: - -```bash -$ vendor/bin/phpbench run --report=aggregate -``` diff --git a/lib/laminas/laminas-servicemanager/bin/generate-deps-for-config-factory b/lib/laminas/laminas-servicemanager/bin/generate-deps-for-config-factory deleted file mode 100644 index 8ee1105a5..000000000 --- a/lib/laminas/laminas-servicemanager/bin/generate-deps-for-config-factory +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env php -=7.4.0" - }, - "type": "library", - "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/1.1.2" - }, - "time": "2021-11-05T16:50:12+00:00" - } - ], - "packages-dev": [ - { - "name": "amphp/amp", - "version": "v2.6.2", - "source": { - "type": "git", - "url": "https://github.com/amphp/amp.git", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^7 | ^8 | ^9", - "psalm/phar": "^3.11@dev", - "react/promise": "^2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php", - "lib/Internal/functions.php" - ], - "psr-4": { - "Amp\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "https://amphp.org/amp", - "keywords": [ - "async", - "asynchronous", - "awaitable", - "concurrency", - "event", - "event-loop", - "future", - "non-blocking", - "promise" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.2" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2022-02-20T17:52:18+00:00" - }, - { - "name": "amphp/byte-stream", - "version": "v1.8.1", - "source": { - "type": "git", - "url": "https://github.com/amphp/byte-stream.git", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", - "shasum": "" - }, - "require": { - "amphp/amp": "^2", - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.4", - "friendsofphp/php-cs-fixer": "^2.3", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^6 || ^7 || ^8", - "psalm/phar": "^3.11.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php" - ], - "psr-4": { - "Amp\\ByteStream\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "http://amphp.org/byte-stream", - "keywords": [ - "amp", - "amphp", - "async", - "io", - "non-blocking", - "stream" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2021-03-30T17:13:30+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-01-17T14:14:24+00:00" - }, - { - "name": "composer/pcre", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], - "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.0" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-11-17T09:50:14+00:00" - }, - { - "name": "composer/semver", - "version": "3.3.2", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-04-01T19:23:25+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", - "shasum": "" - }, - "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" - }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-02-25T21:32:43+00:00" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2022-02-04T12:51:07+00:00" - }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "v0.1.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "implementation of xdg base directory specification for php", - "support": { - "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", - "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" - }, - "time": "2019-12-04T15:06:13+00:00" - }, - { - "name": "doctrine/annotations", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", - "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^2 || ^3", - "ext-tokenizer": "*", - "php": "^7.2 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^2.0", - "doctrine/coding-standard": "^10", - "phpstan/phpstan": "^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^5.4 || ^6", - "vimeo/psalm": "^4.10" - }, - "suggest": { - "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "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": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/2.0.1" - }, - "time": "2023-02-02T22:02:53+00:00" - }, - { - "name": "doctrine/lexer", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "84a527db05647743d50373e0ec53a152f2cde568" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568", - "reference": "84a527db05647743d50373e0ec53a152f2cde568", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "doctrine/coding-standard": "^10", - "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^9.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "src" - } - }, - "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": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/3.0.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2022-12-15T16:57:16+00:00" - }, - { - "name": "felixfbecker/advanced-json-rpc", - "version": "v3.2.1", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "shasum": "" - }, - "require": { - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "php": "^7.1 || ^8.0", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "AdvancedJsonRpc\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "A more advanced JSONRPC implementation", - "support": { - "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", - "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" - }, - "time": "2021-06-11T22:34:44+00:00" - }, - { - "name": "felixfbecker/language-server-protocol", - "version": "v1.5.2", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-language-server-protocol.git", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpstan/phpstan": "*", - "squizlabs/php_codesniffer": "^3.1", - "vimeo/psalm": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "LanguageServerProtocol\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "PHP classes for the Language Server Protocol", - "keywords": [ - "language", - "microsoft", - "php", - "server" - ], - "support": { - "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", - "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2" - }, - "time": "2022-03-02T22:36:06+00:00" - }, - { - "name": "fidry/cpu-core-counter", - "version": "0.5.1", - "source": { - "type": "git", - "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/b58e5a3933e541dc286cc91fc4f3898bbc6f1623", - "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "fidry/makefile": "^0.2.0", - "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": "^9.5.26 || ^8.5.31", - "theofidry/php-cs-fixer-config": "^1.0", - "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/0.5.1" - }, - "funding": [ - { - "url": "https://github.com/theofidry", - "type": "github" - } - ], - "time": "2022-12-24T12:35:10+00:00" - }, - { - "name": "friendsofphp/proxy-manager-lts", - "version": "v1.0.14", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/proxy-manager-lts.git", - "reference": "a527c9d9d5348e012bd24482d83a5cd643bcbc9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/a527c9d9d5348e012bd24482d83a5cd643bcbc9e", - "reference": "a527c9d9d5348e012bd24482d83a5cd643bcbc9e", - "shasum": "" - }, - "require": { - "laminas/laminas-code": "~3.4.1|^4.0", - "php": ">=7.1", - "symfony/filesystem": "^4.4.17|^5.0|^6.0" - }, - "conflict": { - "laminas/laminas-stdlib": "<3.2.1", - "zendframework/zend-stdlib": "<3.2.1" - }, - "replace": { - "ocramius/proxy-manager": "^2.1" - }, - "require-dev": { - "ext-phar": "*", - "symfony/phpunit-bridge": "^5.4|^6.0" - }, - "type": "library", - "extra": { - "thanks": { - "name": "ocramius/proxy-manager", - "url": "https://github.com/Ocramius/ProxyManager" - } - }, - "autoload": { - "psr-4": { - "ProxyManager\\": "src/ProxyManager" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - } - ], - "description": "Adding support for a wider range of PHP versions to ocramius/proxy-manager", - "homepage": "https://github.com/FriendsOfPHP/proxy-manager-lts", - "keywords": [ - "aop", - "lazy loading", - "proxy", - "proxy pattern", - "service proxies" - ], - "support": { - "issues": "https://github.com/FriendsOfPHP/proxy-manager-lts/issues", - "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.14" - }, - "funding": [ - { - "url": "https://github.com/Ocramius", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ocramius/proxy-manager", - "type": "tidelift" - } - ], - "time": "2023-01-30T10:40:19+00:00" - }, - { - "name": "laminas/laminas-code", - "version": "4.10.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-code.git", - "reference": "ad8b36073f9ac792716478befadca0798cc15635" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/ad8b36073f9ac792716478befadca0798cc15635", - "reference": "ad8b36073f9ac792716478befadca0798cc15635", - "shasum": "" - }, - "require": { - "php": "~8.1.0 || ~8.2.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0.0", - "ext-phar": "*", - "laminas/laminas-coding-standard": "^2.3.0", - "laminas/laminas-stdlib": "^3.6.1", - "phpunit/phpunit": "^10.0.9", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.7.1" - }, - "suggest": { - "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", - "laminas/laminas-stdlib": "Laminas\\Stdlib component" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Code\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", - "homepage": "https://laminas.dev", - "keywords": [ - "code", - "laminas", - "laminasframework" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-code/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-code/issues", - "rss": "https://github.com/laminas/laminas-code/releases.atom", - "source": "https://github.com/laminas/laminas-code" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-03-08T11:55:01+00:00" - }, - { - "name": "laminas/laminas-coding-standard", - "version": "2.5.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-coding-standard.git", - "reference": "c1aaa18a7c860c6932677a3e4ec13161f9fc7d61" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/c1aaa18a7c860c6932677a3e4ec13161f9fc7d61", - "reference": "c1aaa18a7c860c6932677a3e4ec13161f9fc7d61", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", - "php": "^7.4 || ^8.0", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.6", - "webimpress/coding-standard": "^1.2" - }, - "conflict": { - "phpstan/phpdoc-parser": ">=1.6.0" - }, - "type": "phpcodesniffer-standard", - "autoload": { - "psr-4": { - "LaminasCodingStandard\\": "src/LaminasCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Laminas Coding Standard", - "homepage": "https://laminas.dev", - "keywords": [ - "Coding Standard", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-coding-standard/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-coding-standard/issues", - "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", - "source": "https://github.com/laminas/laminas-coding-standard" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-01-05T15:53:40+00:00" - }, - { - "name": "laminas/laminas-container-config-test", - "version": "0.8.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-container-config-test.git", - "reference": "06474faed18a2732b21355297fa8c56f1aff2e91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-container-config-test/zipball/06474faed18a2732b21355297fa8c56f1aff2e91", - "reference": "06474faed18a2732b21355297fa8c56f1aff2e91", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "psr/container": "^1.0 || ^2.0" - }, - "conflict": { - "zendframework/zend-container-config-test": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.3", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.0", - "vimeo/psalm": "^4.29.0" - }, - "type": "library", - "autoload": { - "files": [ - "src/TestAsset/function-factory.php", - "src/TestAsset/function-factory-with-name.php", - "src/TestAsset/function-factory.legacy.php", - "src/TestAsset/function-factory-with-name.legacy.php" - ], - "psr-4": { - "Laminas\\ContainerConfigTest\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Mezzio PSR-11 container configuration tests", - "homepage": "https://laminas.dev", - "keywords": [ - "PSR-11", - "container", - "laminas", - "mezzio", - "test" - ], - "support": { - "chat": "https://laminas.dev/chat", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-container-config-test/issues", - "rss": "https://github.com/laminas/laminas-container-config-test/releases.atom", - "source": "https://github.com/laminas/laminas-container-config-test" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-11-16T00:42:21+00:00" - }, - { - "name": "mikey179/vfsstream", - "version": "v1.6.11", - "source": { - "type": "git", - "url": "https://github.com/bovigo/vfsStream.git", - "reference": "17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f", - "reference": "17d16a85e6c26ce1f3e2fa9ceeacdc2855db1e9f", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.5|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, - "autoload": { - "psr-0": { - "org\\bovigo\\vfs\\": "src/main/php" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Frank Kleine", - "homepage": "http://frankkleine.de/", - "role": "Developer" - } - ], - "description": "Virtual file system to mock the real file system in unit tests.", - "homepage": "http://vfs.bovigo.org/", - "support": { - "issues": "https://github.com/bovigo/vfsStream/issues", - "source": "https://github.com/bovigo/vfsStream/tree/master", - "wiki": "https://github.com/bovigo/vfsStream/wiki" - }, - "time": "2022-02-23T02:02:42+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "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" - }, - "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.11.1" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2023-03-08T13:26:56+00:00" - }, - { - "name": "netresearch/jsonmapper", - "version": "v4.2.0", - "source": { - "type": "git", - "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "f60565f8c0566a31acf06884cdaa591867ecc956" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/f60565f8c0566a31acf06884cdaa591867ecc956", - "reference": "f60565f8c0566a31acf06884cdaa591867ecc956", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", - "squizlabs/php_codesniffer": "~3.5" - }, - "type": "library", - "autoload": { - "psr-0": { - "JsonMapper": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "OSL-3.0" - ], - "authors": [ - { - "name": "Christian Weiske", - "email": "cweiske@cweiske.de", - "homepage": "http://github.com/cweiske/jsonmapper/", - "role": "Developer" - } - ], - "description": "Map nested JSON structures onto PHP classes", - "support": { - "email": "cweiske@cweiske.de", - "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v4.2.0" - }, - "time": "2023-04-09T17:37:40+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.17.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-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/v4.17.1" - }, - "time": "2023-08-13T19:53:39+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "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.3" - }, - "time": "2021-07-20T11:28:43+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": "phpbench/container", - "version": "2.2.1", - "source": { - "type": "git", - "url": "https://github.com/phpbench/container.git", - "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpbench/container/zipball/6d555ff7174fca13f9b1ec0b4a089ed41d0ab392", - "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392", - "shasum": "" - }, - "require": { - "psr/container": "^1.0|^2.0", - "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "phpstan/phpstan": "^0.12.52", - "phpunit/phpunit": "^8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "PhpBench\\DependencyInjection\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Leech", - "email": "daniel@dantleech.com" - } - ], - "description": "Simple, configurable, service container.", - "support": { - "issues": "https://github.com/phpbench/container/issues", - "source": "https://github.com/phpbench/container/tree/2.2.1" - }, - "time": "2022-01-25T10:17:35+00:00" - }, - { - "name": "phpbench/dom", - "version": "0.3.3", - "source": { - "type": "git", - "url": "https://github.com/phpbench/dom.git", - "reference": "786a96db538d0def931f5b19225233ec42ec7a72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpbench/dom/zipball/786a96db538d0def931f5b19225233ec42ec7a72", - "reference": "786a96db538d0def931f5b19225233ec42ec7a72", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "php": "^7.3||^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.14", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^8.0||^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "PhpBench\\Dom\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Leech", - "email": "daniel@dantleech.com" - } - ], - "description": "DOM wrapper to simplify working with the PHP DOM implementation", - "support": { - "issues": "https://github.com/phpbench/dom/issues", - "source": "https://github.com/phpbench/dom/tree/0.3.3" - }, - "time": "2023-03-06T23:46:57+00:00" - }, - { - "name": "phpbench/phpbench", - "version": "1.2.10", - "source": { - "type": "git", - "url": "https://github.com/phpbench/phpbench.git", - "reference": "95206f92479674599a75e02b74b9933e2d9883aa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpbench/phpbench/zipball/95206f92479674599a75e02b74b9933e2d9883aa", - "reference": "95206f92479674599a75e02b74b9933e2d9883aa", - "shasum": "" - }, - "require": { - "doctrine/annotations": "^1.13 || ^2.0", - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0", - "phpbench/container": "^2.1", - "phpbench/dom": "~0.3.3", - "psr/log": "^1.1 || ^2.0 || ^3.0", - "seld/jsonlint": "^1.1", - "symfony/console": "^4.2 || ^5.0 || ^6.0", - "symfony/filesystem": "^4.2 || ^5.0 || ^6.0", - "symfony/finder": "^4.2 || ^5.0 || ^6.0", - "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0", - "symfony/process": "^4.2 || ^5.0 || ^6.0", - "webmozart/glob": "^4.6" - }, - "require-dev": { - "dantleech/invoke": "^2.0", - "friendsofphp/php-cs-fixer": "^3.0", - "jangregor/phpstan-prophecy": "^1.0", - "phpspec/prophecy": "^1.12", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.0", - "symfony/error-handler": "^5.2 || ^6.0", - "symfony/var-dumper": "^4.0 || ^5.0 || ^6.0" - }, - "suggest": { - "ext-xdebug": "For Xdebug profiling extension." - }, - "bin": [ - "bin/phpbench" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "files": [ - "lib/Report/Func/functions.php" - ], - "psr-4": { - "PhpBench\\": "lib/", - "PhpBench\\Extensions\\XDebug\\": "extensions/xdebug/lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Leech", - "email": "daniel@dantleech.com" - } - ], - "description": "PHP Benchmarking Framework", - "support": { - "issues": "https://github.com/phpbench/phpbench/issues", - "source": "https://github.com/phpbench/phpbench/tree/1.2.10" - }, - "funding": [ - { - "url": "https://github.com/dantleech", - "type": "github" - } - ], - "time": "2023-03-24T08:52:55+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.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "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": "account@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.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "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.6.2" - }, - "time": "2022-10-14T12:47:21+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "981cc368a216c988e862a75e526b6076987d1b50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50", - "reference": "981cc368a216c988e862a75e526b6076987d1b50", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "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/1.5.1" - }, - "time": "2022-05-05T11:32:40+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "10.1.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "355324ca4980b8916c18b9db29f3ef484078f26e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/355324ca4980b8916c18b9db29f3ef484078f26e", - "reference": "355324ca4980b8916c18b9db29f3ef484078f26e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.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": "10.1-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/10.1.7" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-10-04T15:34:17+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "4.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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": "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/4.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T06:24:48+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "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": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:56:09+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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": "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/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T14:07:24+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "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", - "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", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:57:52+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "10.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "62bd7af13d282deeb95650077d28ba3600ca321c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/62bd7af13d282deeb95650077d28ba3600ca321c", - "reference": "62bd7af13d282deeb95650077d28ba3600ca321c", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "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": ">=8.1", - "phpunit/php-code-coverage": "^10.1.5", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-invoker": "^4.0", - "phpunit/php-text-template": "^3.0", - "phpunit/php-timer": "^6.0", - "sebastian/cli-parser": "^2.0", - "sebastian/code-unit": "^2.0", - "sebastian/comparator": "^5.0", - "sebastian/diff": "^5.0", - "sebastian/environment": "^6.0", - "sebastian/exporter": "^5.1", - "sebastian/global-state": "^6.0.1", - "sebastian/object-enumerator": "^5.0", - "sebastian/recursion-context": "^5.0", - "sebastian/type": "^4.0", - "sebastian/version": "^4.0" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "10.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/10.4.1" - }, - "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": "2023-10-08T05:01:11+00:00" - }, - { - "name": "psalm/plugin-phpunit", - "version": "0.18.4", - "source": { - "type": "git", - "url": "https://github.com/psalm/psalm-plugin-phpunit.git", - "reference": "e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc", - "reference": "e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc", - "shasum": "" - }, - "require": { - "composer/package-versions-deprecated": "^1.10", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "ext-simplexml": "*", - "php": "^7.1 || ^8.0", - "vimeo/psalm": "dev-master || dev-4.x || ^4.7.1 || ^5@beta || ^5.0" - }, - "conflict": { - "phpunit/phpunit": "<7.5" - }, - "require-dev": { - "codeception/codeception": "^4.0.3", - "php": "^7.3 || ^8.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0", - "squizlabs/php_codesniffer": "^3.3.1", - "weirdan/codeception-psalm-module": "^0.11.0", - "weirdan/prophecy-shim": "^1.0 || ^2.0" - }, - "type": "psalm-plugin", - "extra": { - "psalm": { - "pluginClass": "Psalm\\PhpUnitPlugin\\Plugin" - } - }, - "autoload": { - "psr-4": { - "Psalm\\PhpUnitPlugin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Brown", - "email": "github@muglug.com" - } - ], - "description": "Psalm plugin for PHPUnit", - "support": { - "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", - "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.18.4" - }, - "time": "2022-12-03T07:47:07+00:00" - }, - { - "name": "psr/cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/3.0.0" - }, - "time": "2021-02-03T23:26:27+00:00" - }, - { - "name": "psr/log", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", - "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.0" - }, - "time": "2021-07-14T16:46:02+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", - "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.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", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:15+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.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", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:43+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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" - } - ], - "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", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:59:15+00:00" - }, - { - "name": "sebastian/comparator", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.3" - }, - "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" - }, - { - "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/5.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-14T13:18:12+00:00" - }, - { - "name": "sebastian/complexity", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", - "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.10", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.1-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/3.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-09-28T11:50:59+00:00" - }, - { - "name": "sebastian/diff", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^4.2 || ^5" - }, - "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" - }, - { - "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/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-05-01T07:48:21+00:00" - }, - { - "name": "sebastian/environment", - "version": "6.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-posix": "*" - }, - "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" - } - ], - "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/6.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-04-11T05:39:26+00:00" - }, - { - "name": "sebastian/exporter", - "version": "5.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", - "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.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/5.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-09-24T13:22:09+00:00" - }, - { - "name": "sebastian/global-state", - "version": "6.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", - "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^10.0" - }, - "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" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://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/6.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-07-19T07:19:23+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", - "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.10", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.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/2.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T09:25:50+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.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" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:08:32+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:06:18+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:05:40+00:00" - }, - { - "name": "sebastian/type", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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": "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/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:10:45+00:00" - }, - { - "name": "sebastian/version", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "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 that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-07T11:34:05+00:00" - }, - { - "name": "seld/jsonlint", - "version": "1.9.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "4211420d25eba80712bff236a98960ef68b866b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", - "reference": "4211420d25eba80712bff236a98960ef68b866b7", - "shasum": "" - }, - "require": { - "php": "^5.3 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.5", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" - }, - "bin": [ - "bin/jsonlint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Seld\\JsonLint\\": "src/Seld/JsonLint/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "JSON Linter", - "keywords": [ - "json", - "linter", - "parser", - "validator" - ], - "support": { - "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" - }, - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", - "type": "tidelift" - } - ], - "time": "2022-04-01T13:37:23+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "7.2.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phing/phing": "2.17.3", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.7.1", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2022-05-25T10:58:12+00:00" - }, - { - "name": "spatie/array-to-xml", - "version": "3.1.5", - "source": { - "type": "git", - "url": "https://github.com/spatie/array-to-xml.git", - "reference": "13f76acef5362d15c71ae1ac6350cc3df5e25e43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/13f76acef5362d15c71ae1ac6350cc3df5e25e43", - "reference": "13f76acef5362d15c71ae1ac6350cc3df5e25e43", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "php": "^8.0" - }, - "require-dev": { - "mockery/mockery": "^1.2", - "pestphp/pest": "^1.21", - "spatie/pest-plugin-snapshots": "^1.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\ArrayToXml\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://freek.dev", - "role": "Developer" - } - ], - "description": "Convert an array to xml", - "homepage": "https://github.com/spatie/array-to-xml", - "keywords": [ - "array", - "convert", - "xml" - ], - "support": { - "source": "https://github.com/spatie/array-to-xml/tree/3.1.5" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - }, - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2022-12-24T13:43:51+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.2", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2023-02-22T23:07:41+00:00" - }, - { - "name": "symfony/console", - "version": "v6.2.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3582d68a64a86ec25240aaa521ec8bc2342b369b", - "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.4|^6.0" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command-line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v6.2.8" - }, - "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-03-29T21:42:15+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" - }, - "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-05-23T14:45:45+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v6.2.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "82b6c62b959f642d000456f08c6d219d749215b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/82b6c62b959f642d000456f08c6d219d749215b3", - "reference": "82b6c62b959f642d000456f08c6d219d749215b3", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.2.7" - }, - "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-02-14T08:44:56+00:00" - }, - { - "name": "symfony/finder", - "version": "v6.2.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/20808dc6631aecafbe67c186af5dcb370be3a0eb", - "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "symfony/filesystem": "^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v6.2.7" - }, - "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-02-16T09:57:23+00:00" - }, - { - "name": "symfony/options-resolver", - "version": "v6.2.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "aa0e85b53bbb2b4951960efd61d295907eacd629" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/aa0e85b53bbb2b4951960efd61d295907eacd629", - "reference": "aa0e85b53bbb2b4951960efd61d295907eacd629", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an improved replacement for the array_replace PHP function", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.2.7" - }, - "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-02-14T08:44:56+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "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\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" - }, - "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-01-26T09:26:14+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "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" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/process", - "version": "v6.2.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "75ed64103df4f6615e15a7fe38b8111099f47416" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/75ed64103df4f6615e15a7fe38b8111099f47416", - "reference": "75ed64103df4f6615e15a7fe38b8111099f47416", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v6.2.8" - }, - "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-03-09T16:20:02+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v2.5.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" - }, - "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": "2022-05-30T19:17:29+00:00" - }, - { - "name": "symfony/string", - "version": "v6.2.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef", - "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.0" - }, - "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.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", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v6.2.8" - }, - "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-03-20T16:06:02+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "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" - } - ], - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "vimeo/psalm", - "version": "5.9.0", - "source": { - "type": "git", - "url": "https://github.com/vimeo/psalm.git", - "reference": "8b9ad1eb9e8b7d3101f949291da2b9f7767cd163" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/8b9ad1eb9e8b7d3101f949291da2b9f7767cd163", - "reference": "8b9ad1eb9e8b7d3101f949291da2b9f7767cd163", - "shasum": "" - }, - "require": { - "amphp/amp": "^2.4.2", - "amphp/byte-stream": "^1.5", - "composer-runtime-api": "^2", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^2.0 || ^3.0", - "dnoegel/php-xdg-base-dir": "^0.1.1", - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*", - "felixfbecker/advanced-json-rpc": "^3.1", - "felixfbecker/language-server-protocol": "^1.5.2", - "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1", - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "nikic/php-parser": "^4.14", - "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0", - "sebastian/diff": "^4.0 || ^5.0", - "spatie/array-to-xml": "^2.17.0 || ^3.0", - "symfony/console": "^4.1.6 || ^5.0 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0" - }, - "provide": { - "psalm/psalm": "self.version" - }, - "require-dev": { - "amphp/phpunit-util": "^2.0", - "bamarni/composer-bin-plugin": "^1.4", - "brianium/paratest": "^6.9", - "ext-curl": "*", - "mockery/mockery": "^1.5", - "nunomaduro/mock-final-classes": "^1.1", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpdoc-parser": "^1.6", - "phpunit/phpunit": "^9.6", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.6", - "symfony/process": "^4.4 || ^5.0 || ^6.0" - }, - "suggest": { - "ext-curl": "In order to send data to shepherd", - "ext-igbinary": "^2.0.5 is required, used to serialize caching data" - }, - "bin": [ - "psalm", - "psalm-language-server", - "psalm-plugin", - "psalm-refactor", - "psalter" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev", - "dev-4.x": "4.x-dev", - "dev-3.x": "3.x-dev", - "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psalm\\": "src/Psalm/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthew Brown" - } - ], - "description": "A static analysis tool for finding errors in PHP applications", - "keywords": [ - "code", - "inspection", - "php", - "static analysis" - ], - "support": { - "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm/tree/5.9.0" - }, - "time": "2023-03-29T21:38:21+00:00" - }, - { - "name": "webimpress/coding-standard", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/webimpress/coding-standard.git", - "reference": "b26557e2386711ecb74f22718f4b4bde5ddbc899" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/b26557e2386711ecb74f22718f4b4bde5ddbc899", - "reference": "b26557e2386711ecb74f22718f4b4bde5ddbc899", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "squizlabs/php_codesniffer": "^3.7.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.6.4" - }, - "type": "phpcodesniffer-standard", - "extra": { - "dev-master": "1.2.x-dev", - "dev-develop": "1.3.x-dev" - }, - "autoload": { - "psr-4": { - "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "description": "Webimpress Coding Standard", - "keywords": [ - "Coding Standard", - "PSR-2", - "phpcs", - "psr-12", - "webimpress" - ], - "support": { - "issues": "https://github.com/webimpress/coding-standard/issues", - "source": "https://github.com/webimpress/coding-standard/tree/1.3.1" - }, - "funding": [ - { - "url": "https://github.com/michalbundyra", - "type": "github" - } - ], - "time": "2023-03-09T15:05:18+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" - }, - { - "name": "webmozart/glob", - "version": "4.6.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/glob.git", - "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/glob/zipball/3c17f7dec3d9d0e87b575026011f2e75a56ed655", - "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5", - "symfony/filesystem": "^5.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Glob\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "A PHP implementation of Ant's glob.", - "support": { - "issues": "https://github.com/webmozarts/glob/issues", - "source": "https://github.com/webmozarts/glob/tree/4.6.0" - }, - "time": "2022-05-24T19:45:58+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "platform-dev": [], - "platform-overrides": { - "php": "8.1.99" - }, - "plugin-api-version": "2.6.0" -} diff --git a/lib/laminas/laminas-servicemanager/src/AbstractFactory/ConfigAbstractFactory.php b/lib/laminas/laminas-servicemanager/src/AbstractFactory/ConfigAbstractFactory.php deleted file mode 100644 index 3b58ad8f6..000000000 --- a/lib/laminas/laminas-servicemanager/src/AbstractFactory/ConfigAbstractFactory.php +++ /dev/null @@ -1,78 +0,0 @@ -has('config')) { - return false; - } - $config = $container->get('config'); - if (! isset($config[self::class])) { - return false; - } - $dependencies = $config[self::class]; - - return is_array($dependencies) && array_key_exists($requestedName, $dependencies); - } - - /** {@inheritDoc} */ - public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null) - { - if (! $container->has('config')) { - throw new ServiceNotCreatedException('Cannot find a config array in the container'); - } - - $config = $container->get('config'); - - if (! (is_array($config) || $config instanceof ArrayObject)) { - throw new ServiceNotCreatedException('Config must be an array or an instance of ArrayObject'); - } - if (! isset($config[self::class])) { - throw new ServiceNotCreatedException('Cannot find a `' . self::class . '` key in the config array'); - } - - $dependencies = $config[self::class]; - - if ( - ! is_array($dependencies) - || ! array_key_exists($requestedName, $dependencies) - || ! is_array($dependencies[$requestedName]) - ) { - throw new ServiceNotCreatedException('Service dependencies config must exist and be an array'); - } - - $serviceDependencies = $dependencies[$requestedName]; - - if ($serviceDependencies !== array_values(array_map('strval', $serviceDependencies))) { - $problem = json_encode(array_map('gettype', $serviceDependencies)); - throw new ServiceNotCreatedException( - 'Service dependencies config must be an array of strings, ' . $problem . ' given' - ); - } - - $arguments = array_map([$container, 'get'], $serviceDependencies); - - return new $requestedName(...$arguments); - } -} diff --git a/lib/laminas/laminas-servicemanager/src/AbstractFactory/ReflectionBasedAbstractFactory.php b/lib/laminas/laminas-servicemanager/src/AbstractFactory/ReflectionBasedAbstractFactory.php deleted file mode 100644 index 4f4654bd5..000000000 --- a/lib/laminas/laminas-servicemanager/src/AbstractFactory/ReflectionBasedAbstractFactory.php +++ /dev/null @@ -1,245 +0,0 @@ - - * 'service_manager' => [ - * 'abstract_factories' => [ - * ReflectionBasedAbstractFactory::class, - * ], - * ], - * - * - * Or as a factory, mapping a class name to it: - * - * - * 'service_manager' => [ - * 'factories' => [ - * MyClassWithDependencies::class => ReflectionBasedAbstractFactory::class, - * ], - * ], - * - * - * The latter approach is more explicit, and also more performant. - * - * The factory has the following constraints/features: - * - * - A parameter named `$config` typehinted as an array will receive the - * application "config" service (i.e., the merged configuration). - * - Parameters type-hinted against array, but not named `$config` will - * be injected with an empty array. - * - Scalar parameters will result in an exception being thrown, unless - * a default value is present; if the default is present, that will be used. - * - If a service cannot be found for a given typehint, the factory will - * raise an exception detailing this. - * - Some services provided by Laminas components do not have - * entries based on their class name (for historical reasons); the - * factory allows defining a map of these class/interface names to the - * corresponding service name to allow them to resolve. - * - * `$options` passed to the factory are ignored in all cases, as we cannot - * make assumptions about which argument(s) they might replace. - * - * Based on the LazyControllerAbstractFactory from laminas-mvc. - */ -class ReflectionBasedAbstractFactory implements AbstractFactoryInterface -{ - /** - * Maps known classes/interfaces to the service that provides them; only - * required for those services with no entry based on the class/interface - * name. - * - * Extend the class if you wish to add to the list. - * - * Example: - * - * - * [ - * \Laminas\Filter\FilterPluginManager::class => 'FilterManager', - * \Laminas\Validator\ValidatorPluginManager::class => 'ValidatorManager', - * ] - * - * - * @var string[] - */ - protected $aliases = []; - - /** - * Allows overriding the internal list of aliases. These should be of the - * form `class name => well-known service name`; see the documentation for - * the `$aliases` property for details on what is accepted. - * - * @param string[] $aliases - */ - public function __construct(array $aliases = []) - { - if (! empty($aliases)) { - $this->aliases = $aliases; - } - } - - /** - * {@inheritDoc} - * - * @return DispatchableInterface - */ - public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null) - { - $reflectionClass = new ReflectionClass($requestedName); - - if (null === ($constructor = $reflectionClass->getConstructor())) { - return new $requestedName(); - } - - $reflectionParameters = $constructor->getParameters(); - - if (empty($reflectionParameters)) { - return new $requestedName(); - } - - $resolver = $container->has('config') - ? $this->resolveParameterWithConfigService($container, $requestedName) - : $this->resolveParameterWithoutConfigService($container, $requestedName); - - $parameters = array_map($resolver, $reflectionParameters); - - return new $requestedName(...$parameters); - } - - /** {@inheritDoc} */ - public function canCreate(ContainerInterface $container, $requestedName) - { - return class_exists($requestedName) && $this->canCallConstructor($requestedName); - } - - private function canCallConstructor(string $requestedName): bool - { - $constructor = (new ReflectionClass($requestedName))->getConstructor(); - - return $constructor === null || $constructor->isPublic(); - } - - /** - * Resolve a parameter to a value. - * - * Returns a callback for resolving a parameter to a value, but without - * allowing mapping array `$config` arguments to the `config` service. - * - * @param string $requestedName - * @return callable - */ - private function resolveParameterWithoutConfigService(ContainerInterface $container, $requestedName) - { - /** - * @param ReflectionParameter $parameter - * @return mixed - * @throws ServiceNotFoundException If type-hinted parameter cannot be - * resolved to a service in the container. - * @psalm-suppress MissingClosureReturnType - */ - return fn(ReflectionParameter $parameter) => $this->resolveParameter($parameter, $container, $requestedName); - } - - /** - * Returns a callback for resolving a parameter to a value, including mapping 'config' arguments. - * - * Unlike resolveParameter(), this version will detect `$config` array - * arguments and have them return the 'config' service. - * - * @param string $requestedName - * @return callable - */ - private function resolveParameterWithConfigService(ContainerInterface $container, $requestedName) - { - /** - * @param ReflectionParameter $parameter - * @return mixed - * @throws ServiceNotFoundException If type-hinted parameter cannot be - * resolved to a service in the container. - */ - return function (ReflectionParameter $parameter) use ($container, $requestedName) { - if ($parameter->getName() === 'config') { - $type = $parameter->getType(); - if ($type instanceof ReflectionNamedType && $type->getName() === 'array') { - return $container->get('config'); - } - } - return $this->resolveParameter($parameter, $container, $requestedName); - }; - } - - /** - * Logic common to all parameter resolution. - * - * @param string $requestedName - * @return mixed - * @throws ServiceNotFoundException If type-hinted parameter cannot be - * resolved to a service in the container. - */ - private function resolveParameter(ReflectionParameter $parameter, ContainerInterface $container, $requestedName) - { - $type = $parameter->getType(); - $type = $type instanceof ReflectionNamedType ? $type->getName() : null; - - if ($type === 'array') { - return []; - } - - if ($type === null || (is_string($type) && ! class_exists($type) && ! interface_exists($type))) { - if (! $parameter->isDefaultValueAvailable()) { - throw new ServiceNotFoundException(sprintf( - 'Unable to create service "%s"; unable to resolve parameter "%s" ' - . 'to a class, interface, or array type', - $requestedName, - $parameter->getName() - )); - } - - return $parameter->getDefaultValue(); - } - - $type = $this->aliases[$type] ?? $type; - - if ($container->has($type)) { - return $container->get($type); - } - - if (! $parameter->isOptional()) { - throw new ServiceNotFoundException(sprintf( - 'Unable to create service "%s"; unable to resolve parameter "%s" using type hint "%s"', - $requestedName, - $parameter->getName(), - $type - )); - } - - // Type not available in container, but the value is optional and has a - // default defined. - return $parameter->getDefaultValue(); - } -} diff --git a/lib/laminas/laminas-servicemanager/src/AbstractFactoryInterface.php b/lib/laminas/laminas-servicemanager/src/AbstractFactoryInterface.php deleted file mode 100644 index 2a8ff71b2..000000000 --- a/lib/laminas/laminas-servicemanager/src/AbstractFactoryInterface.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @psalm-import-type ServiceManagerConfiguration from ServiceManager - * @psalm-suppress PropertyNotSetInConstructor - */ -abstract class AbstractPluginManager extends ServiceManager implements PluginManagerInterface -{ - /** - * Whether or not to auto-add a FQCN as an invokable if it exists. - * - * @var bool - */ - protected $autoAddInvokableClass = true; - - /** - * An object type that the created instance must be instanced of - * - * @var null|string - * @psalm-var null|class-string - */ - protected $instanceOf; - - /** - * Sets the provided $parentLocator as the creation context for all - * factories; for $config, {@see \Laminas\ServiceManager\ServiceManager::configure()} - * for details on its accepted structure. - * - * @param null|ConfigInterface|ContainerInterface $configInstanceOrParentLocator - * @param array $config - * @psalm-param ServiceManagerConfiguration $config - */ - public function __construct($configInstanceOrParentLocator = null, array $config = []) - { - /** @psalm-suppress DocblockTypeContradiction */ - if ( - null !== $configInstanceOrParentLocator - && ! $configInstanceOrParentLocator instanceof ConfigInterface - && ! $configInstanceOrParentLocator instanceof ContainerInterface - ) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects a ConfigInterface or ContainerInterface instance as the first argument; received %s', - self::class, - is_object($configInstanceOrParentLocator) - ? $configInstanceOrParentLocator::class - : gettype($configInstanceOrParentLocator) - )); - } - - if ($configInstanceOrParentLocator instanceof ConfigInterface) { - trigger_error(sprintf( - 'Usage of %s as a constructor argument for %s is now deprecated', - ConfigInterface::class, - static::class - ), E_USER_DEPRECATED); - $config = $configInstanceOrParentLocator->toArray(); - } - - parent::__construct($config); - - if (! $configInstanceOrParentLocator instanceof ContainerInterface) { - trigger_error(sprintf( - '%s now expects a %s instance representing the parent container; please update your code', - __METHOD__, - ContainerInterface::class - ), E_USER_DEPRECATED); - } - - $this->creationContext = $configInstanceOrParentLocator instanceof ContainerInterface - ? $configInstanceOrParentLocator - : $this; - } - - /** - * Override configure() to validate service instances. - * - * @param array $config - * @psalm-param ServiceManagerConfiguration $config - * @return self - * @throws InvalidServiceException If an instance passed in the `services` configuration is invalid for the - * plugin manager. - * @throws ContainerModificationsNotAllowedException If the allow override flag has been toggled off, and a - * service instanceexists for a given service. - */ - public function configure(array $config) - { - if (isset($config['services'])) { - foreach ($config['services'] as $service) { - $this->validate($service); - } - } - - parent::configure($config); - - return $this; - } - - /** - * Override setService for additional plugin validation. - * - * {@inheritDoc} - * - * @param string|class-string $name - * @param InstanceType $service - */ - public function setService($name, $service) - { - $this->validate($service); - parent::setService($name, $service); - } - - /** - * @param class-string|string $name Service name of plugin to retrieve. - * @param null|array $options Options to use when creating the instance. - * @return mixed - * @psalm-return ($name is class-string ? InstanceType : mixed) - * @throws Exception\ServiceNotFoundException If the manager does not have - * a service definition for the instance, and the service is not - * auto-invokable. - * @throws InvalidServiceException If the plugin created is invalid for the - * plugin context. - */ - public function get($name, ?array $options = null) - { - if (! $this->has($name)) { - if (! $this->autoAddInvokableClass || ! class_exists($name)) { - throw new Exception\ServiceNotFoundException(sprintf( - 'A plugin by the name "%s" was not found in the plugin manager %s', - $name, - static::class - )); - } - - $this->setFactory($name, Factory\InvokableFactory::class); - } - - $instance = ! $options ? parent::get($name) : $this->build($name, $options); - $this->validate($instance); - return $instance; - } - - /** - * {@inheritDoc} - * - * @psalm-assert InstanceType $instance - */ - public function validate(mixed $instance) - { - if (method_exists($this, 'validatePlugin')) { - trigger_error(sprintf( - '%s::validatePlugin() has been deprecated as of 3.0; please define validate() instead', - static::class - ), E_USER_DEPRECATED); - $this->validatePlugin($instance); - return; - } - - if (empty($this->instanceOf) || $instance instanceof $this->instanceOf) { - return; - } - - throw new InvalidServiceException(sprintf( - 'Plugin manager "%s" expected an instance of type "%s", but "%s" was received', - self::class, - $this->instanceOf, - is_object($instance) ? $instance::class : gettype($instance) - )); - } - - /** - * Implemented for backwards compatibility only. - * - * Returns the creation context. - * - * @deprecated since 3.0.0. The creation context should be passed during - * instantiation instead. - * - * @return void - */ - public function setServiceLocator(ContainerInterface $container) - { - trigger_error(sprintf( - 'Usage of %s is deprecated since v3.0.0; please pass the container to the constructor instead', - __METHOD__ - ), E_USER_DEPRECATED); - $this->creationContext = $container; - } -} diff --git a/lib/laminas/laminas-servicemanager/src/Config.php b/lib/laminas/laminas-servicemanager/src/Config.php deleted file mode 100644 index b7b6042cc..000000000 --- a/lib/laminas/laminas-servicemanager/src/Config.php +++ /dev/null @@ -1,102 +0,0 @@ - */ - private array $allowedKeys = [ - 'abstract_factories' => true, - 'aliases' => true, - 'delegators' => true, - 'factories' => true, - 'initializers' => true, - 'invokables' => true, - 'lazy_services' => true, - 'services' => true, - 'shared' => true, - ]; - - /** - * @var array - * @psalm-var ServiceManagerConfigurationType - */ - protected $config = [ - 'abstract_factories' => [], - 'aliases' => [], - 'delegators' => [], - 'factories' => [], - 'initializers' => [], - 'invokables' => [], - 'lazy_services' => [], - 'services' => [], - 'shared' => [], - ]; - - /** - * @psalm-param ServiceManagerConfigurationType $config - */ - public function __construct(array $config = []) - { - // Only merge keys we're interested in - foreach (array_keys($config) as $key) { - if (! isset($this->allowedKeys[$key])) { - unset($config[$key]); - } - } - - /** @psalm-suppress ArgumentTypeCoercion */ - $this->config = $this->merge($this->config, $config); - } - - /** - * @inheritDoc - */ - public function configureServiceManager(ServiceManager $serviceManager) - { - return $serviceManager->configure($this->config); - } - - /** - * @inheritDoc - */ - public function toArray() - { - return $this->config; - } - - /** - * @psalm-param ServiceManagerConfigurationType $a - * @psalm-param ServiceManagerConfigurationType $b - * @psalm-return ServiceManagerConfigurationType - */ - private function merge(array $a, array $b) - { - return ArrayUtils::merge($a, $b); - } -} diff --git a/lib/laminas/laminas-servicemanager/src/ConfigInterface.php b/lib/laminas/laminas-servicemanager/src/ConfigInterface.php deleted file mode 100644 index 15fb7e3e0..000000000 --- a/lib/laminas/laminas-servicemanager/src/ConfigInterface.php +++ /dev/null @@ -1,93 +0,0 @@ -|Factory\AbstractFactoryInterface) - * > - * @psalm-type DelegatorsConfigurationType = array< - * string, - * array< - * array-key, - * (class-string|Factory\DelegatorFactoryInterface) - * |callable(ContainerInterface,string,callable():object,array|null):object - * > - * > - * @psalm-type FactoriesConfigurationType = array< - * string, - * (class-string|Factory\FactoryInterface) - * |callable(ContainerInterface,?string,?array|null):object - * > - * @psalm-type InitializersConfigurationType = array< - * array-key, - * (class-string|Initializer\InitializerInterface) - * |callable(ContainerInterface,object):void - * > - * @psalm-type LazyServicesConfigurationType = array{ - * class_map?:array, - * proxies_namespace?:non-empty-string, - * proxies_target_dir?:non-empty-string, - * write_proxy_files?:bool - * } - * @psalm-type ServiceManagerConfigurationType = array{ - * abstract_factories?: AbstractFactoriesConfigurationType, - * aliases?: array, - * delegators?: DelegatorsConfigurationType, - * factories?: FactoriesConfigurationType, - * initializers?: InitializersConfigurationType, - * invokables?: array, - * lazy_services?: LazyServicesConfigurationType, - * services?: array, - * shared?:array, - * ... - * } - */ -interface ConfigInterface -{ - /** - * Configure a service manager. - * - * Implementations should pull configuration from somewhere (typically - * local properties) and pass it to a ServiceManager's withConfig() method, - * returning a new instance. - * - * @return ServiceManager - */ - public function configureServiceManager(ServiceManager $serviceManager); - - /** - * Return configuration for a service manager instance as an array. - * - * Implementations MUST return an array compatible with ServiceManager::configure, - * containing one or more of the following keys: - * - * - abstract_factories - * - aliases - * - delegators - * - factories - * - initializers - * - invokables - * - lazy_services - * - services - * - shared - * - * In other words, this should return configuration that can be used to instantiate - * a service manager or plugin manager, or pass to its `withConfig()` method. - * - * @return array - * @psalm-return ServiceManagerConfigurationType - */ - public function toArray(); -} diff --git a/lib/laminas/laminas-servicemanager/src/DelegatorFactoryInterface.php b/lib/laminas/laminas-servicemanager/src/DelegatorFactoryInterface.php deleted file mode 100644 index 1b30ecf60..000000000 --- a/lib/laminas/laminas-servicemanager/src/DelegatorFactoryInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - ' . $cursor; - } - $cycle .= ' -> ' . $alias . "\n"; - - return new self(sprintf( - "A cycle was detected within the aliases definitions:\n%s", - $cycle - )); - } - - /** - * @param string[] $aliases map of referenced services, indexed by alias name (string) - * @return self - */ - public static function fromAliasesMap(array $aliases) - { - $detectedCycles = array_filter(array_map( - static fn($alias): ?array => self::getCycleFor($aliases, $alias), - array_keys($aliases) - )); - - if (! $detectedCycles) { - return new self(sprintf( - "A cycle was detected within the following aliases map:\n\n%s", - self::printReferencesMap($aliases) - )); - } - - return new self(sprintf( - "Cycles were detected within the provided aliases:\n\n%s\n\n" - . "The cycle was detected in the following alias map:\n\n%s", - self::printCycles(self::deDuplicateDetectedCycles($detectedCycles)), - self::printReferencesMap($aliases) - )); - } - - /** - * Retrieves the cycle detected for the given $alias, or `null` if no cycle was detected - * - * @param string[] $aliases - * @param string $alias - * @return array|null - */ - private static function getCycleFor(array $aliases, $alias) - { - $cycleCandidate = []; - $targetName = $alias; - - while (isset($aliases[$targetName])) { - if (isset($cycleCandidate[$targetName])) { - return $cycleCandidate; - } - - $cycleCandidate[$targetName] = true; - $targetName = $aliases[$targetName]; - } - - return null; - } - - /** - * @param string[] $aliases - * @return string - */ - private static function printReferencesMap(array $aliases) - { - $map = []; - - foreach ($aliases as $alias => $reference) { - $map[] = '"' . $alias . '" => "' . $reference . '"'; - } - - return "[\n" . implode("\n", $map) . "\n]"; - } - - /** - * @param string[][] $detectedCycles - * @return string - */ - private static function printCycles(array $detectedCycles) - { - return "[\n" . implode("\n", array_map([self::class, 'printCycle'], $detectedCycles)) . "\n]"; - } - - /** - * @param string[] $detectedCycle - * @return string - * @phpcsSuppress SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedMethod - */ - private static function printCycle(array $detectedCycle) - { - $fullCycle = array_keys($detectedCycle); - $fullCycle[] = reset($fullCycle); - - return implode( - ' => ', - array_map( - static fn($cycle): string => '"' . $cycle . '"', - $fullCycle - ) - ); - } - - /** - * @param bool[][] $detectedCycles - * @return bool[][] de-duplicated - */ - private static function deDuplicateDetectedCycles(array $detectedCycles) - { - $detectedCyclesByHash = []; - - foreach ($detectedCycles as $detectedCycle) { - $cycleAliases = array_keys($detectedCycle); - - sort($cycleAliases); - - $hash = serialize($cycleAliases); - - $detectedCyclesByHash[$hash] ??= $detectedCycle; - } - - return array_values($detectedCyclesByHash); - } -} diff --git a/lib/laminas/laminas-servicemanager/src/Exception/ExceptionInterface.php b/lib/laminas/laminas-servicemanager/src/Exception/ExceptionInterface.php deleted file mode 100644 index cccc42df5..000000000 --- a/lib/laminas/laminas-servicemanager/src/Exception/ExceptionInterface.php +++ /dev/null @@ -1,14 +0,0 @@ - $options - * @return object - * @throws ServiceNotFoundException If unable to resolve the service. - * @throws ServiceNotCreatedException If an exception is raised when creating a service. - * @throws ContainerExceptionInterface If any other error occurs. - */ - public function __invoke(ContainerInterface $container, $name, callable $callback, ?array $options = null); -} diff --git a/lib/laminas/laminas-servicemanager/src/Factory/FactoryInterface.php b/lib/laminas/laminas-servicemanager/src/Factory/FactoryInterface.php deleted file mode 100644 index 68e61671d..000000000 --- a/lib/laminas/laminas-servicemanager/src/Factory/FactoryInterface.php +++ /dev/null @@ -1,33 +0,0 @@ - $options - * @return object - * @throws ServiceNotFoundException If unable to resolve the service. - * @throws ServiceNotCreatedException If an exception is raised when creating a service. - * @throws ContainerExceptionInterface If any other error occurs. - */ - public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null); -} diff --git a/lib/laminas/laminas-servicemanager/src/Factory/InvokableFactory.php b/lib/laminas/laminas-servicemanager/src/Factory/InvokableFactory.php deleted file mode 100644 index 6f80c8944..000000000 --- a/lib/laminas/laminas-servicemanager/src/Factory/InvokableFactory.php +++ /dev/null @@ -1,27 +0,0 @@ - $servicesMap A map of service names to - * class names of their respective classes - */ - public function __construct(private LazyLoadingValueHolderFactory $proxyFactory, private array $servicesMap) - { - } - - /** - * {@inheritDoc} - * - * @param string $name - * @return VirtualProxyInterface - */ - public function __invoke(ContainerInterface $container, $name, callable $callback, ?array $options = null) - { - if (isset($this->servicesMap[$name])) { - $initializer = static function (&$wrappedInstance, LazyLoadingInterface $proxy) use ($callback): bool { - $proxy->setProxyInitializer(null); - $wrappedInstance = $callback(); - - return true; - }; - - return $this->proxyFactory->createProxy($this->servicesMap[$name], $initializer); - } - - throw new Exception\ServiceNotFoundException( - sprintf('The requested service "%s" was not found in the provided services map', $name) - ); - } -} diff --git a/lib/laminas/laminas-servicemanager/src/ServiceLocatorInterface.php b/lib/laminas/laminas-servicemanager/src/ServiceLocatorInterface.php deleted file mode 100644 index 3d4bd447b..000000000 --- a/lib/laminas/laminas-servicemanager/src/ServiceLocatorInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - $name - * @param null|array $options - * @return mixed - * @psalm-return ($name is class-string ? T : mixed) - * @throws Exception\ServiceNotFoundException If no factory/abstract - * factory could be found to create the instance. - * @throws Exception\ServiceNotCreatedException If factory/delegator fails - * to create the instance. - * @throws ContainerExceptionInterface If any other error occurs. - */ - public function build($name, ?array $options = null); -} diff --git a/lib/laminas/laminas-servicemanager/src/ServiceManager.php b/lib/laminas/laminas-servicemanager/src/ServiceManager.php deleted file mode 100644 index d63e26312..000000000 --- a/lib/laminas/laminas-servicemanager/src/ServiceManager.php +++ /dev/null @@ -1,1010 +0,0 @@ -|Factory\AbstractFactoryInterface) - * > - * @psalm-type DelegatorsConfiguration = array< - * string, - * array< - * array-key, - * (class-string|Factory\DelegatorFactoryInterface) - * |callable(ContainerInterface,string,callable():object,array|null):object - * > - * > - * @psalm-type FactoriesConfiguration = array< - * string, - * (class-string|Factory\FactoryInterface) - * |callable(ContainerInterface,?string,?array|null):object - * > - * @psalm-type InitializersConfiguration = array< - * array-key, - * (class-string|Initializer\InitializerInterface) - * |callable(ContainerInterface,object):void - * > - * @psalm-type LazyServicesConfiguration = array{ - * class_map?:array, - * proxies_namespace?:non-empty-string, - * proxies_target_dir?:non-empty-string, - * write_proxy_files?:bool - * } - * @psalm-type ServiceManagerConfiguration = array{ - * abstract_factories?: AbstractFactoriesConfiguration, - * aliases?: array, - * delegators?: DelegatorsConfiguration, - * factories?: FactoriesConfiguration, - * initializers?: InitializersConfiguration, - * invokables?: array, - * lazy_services?: LazyServicesConfiguration, - * services?: array>, - * shared?:array, - * shared_by_default?:bool, - * ... - * } - */ -class ServiceManager implements ServiceLocatorInterface -{ - /** @var Factory\AbstractFactoryInterface[] */ - protected $abstractFactories = []; - - /** - * A list of aliases - * - * Should map one alias to a service name, or another alias (aliases are recursively resolved) - * - * @var string[] - */ - protected $aliases = []; - - /** - * Whether or not changes may be made to this instance. - * - * @var bool - */ - protected $allowOverride = false; - - /** @var ContainerInterface */ - protected $creationContext; - - /** - * @var string[][]|Factory\DelegatorFactoryInterface[][] - * @psalm-var DelegatorsConfiguration - */ - protected $delegators = []; - - /** - * A list of factories (either as string name or callable) - * - * @var string[]|callable[] - * @psalm-var FactoriesConfiguration - */ - protected $factories = []; - - /** - * @var Initializer\InitializerInterface[]|callable[] - * @psalm-var InitializersConfiguration - */ - protected $initializers = []; - - /** - * @var array - * @psalm-var LazyServicesConfiguration - */ - protected $lazyServices = []; - - private ?LazyServiceFactory $lazyServicesDelegator = null; - - /** - * A list of already loaded services (this act as a local cache) - * - * @var array - */ - protected $services = []; - - /** - * Enable/disable shared instances by service name. - * - * Example configuration: - * - * 'shared' => [ - * MyService::class => true, // will be shared, even if "sharedByDefault" is false - * MyOtherService::class => false // won't be shared, even if "sharedByDefault" is true - * ] - * - * @var array - */ - protected $shared = []; - - /** - * Should the services be shared by default? - * - * @var bool - */ - protected $sharedByDefault = true; - - /** - * Service manager was already configured? - * - * @var bool - */ - protected $configured = false; - - /** - * Cached abstract factories from string. - */ - private array $cachedAbstractFactories = []; - - /** - * See {@see \Laminas\ServiceManager\ServiceManager::configure()} for details - * on what $config accepts. - * - * @psalm-param ServiceManagerConfiguration $config - */ - public function __construct(array $config = []) - { - $this->creationContext = $this; - $this->configure($config); - } - - /** - * Implemented for backwards compatibility with previous plugin managers only. - * - * Returns the creation context. - * - * @deprecated since 3.0.0. Factories using 3.0 should use the container - * instance passed to the factory instead. - * - * @return ContainerInterface - */ - public function getServiceLocator() - { - trigger_error(sprintf( - 'Usage of %s is deprecated since v3.0.0; please use the container passed to the factory instead', - __METHOD__ - ), E_USER_DEPRECATED); - return $this->creationContext; - } - - /** {@inheritDoc} */ - public function get($name) - { - // We start by checking if we have cached the requested service; - // this is the fastest method. - if (isset($this->services[$name])) { - return $this->services[$name]; - } - - // Determine if the service should be shared. - $sharedService = $this->shared[$name] ?? $this->sharedByDefault; - - // We achieve better performance if we can let all alias - // considerations out. - if (! $this->aliases) { - $object = $this->doCreate($name); - - // Cache the object for later, if it is supposed to be shared. - if ($sharedService) { - $this->services[$name] = $object; - } - return $object; - } - - // We now deal with requests which may be aliases. - $resolvedName = $this->aliases[$name] ?? $name; - - // Update shared service information as we checked if the alias was shared before. - if ($resolvedName !== $name) { - $sharedService = $this->shared[$resolvedName] ?? $sharedService; - } - - // The following is only true if the requested service is a shared alias. - $sharedAlias = $sharedService && isset($this->services[$resolvedName]); - - // If the alias is configured as a shared service, we are done. - if ($sharedAlias) { - $this->services[$name] = $this->services[$resolvedName]; - return $this->services[$resolvedName]; - } - - // At this point, we have to create the object. - // We use the resolved name for that. - $object = $this->doCreate($resolvedName); - - // Cache the object for later, if it is supposed to be shared. - if ($sharedService) { - $this->services[$resolvedName] = $object; - } - - // Also cache under the alias name; this allows sharing based on the - // service name used. - if ($sharedAlias) { - $this->services[$name] = $object; - } - - return $object; - } - - /** {@inheritDoc} */ - public function build($name, ?array $options = null) - { - // We never cache when using "build". - $name = $this->aliases[$name] ?? $name; - return $this->doCreate($name, $options); - } - - /** - * {@inheritDoc} - * - * @param string|class-string $name - * @return bool - */ - public function has($name) - { - // Check static services and factories first to speedup the most common requests. - return $this->staticServiceOrFactoryCanCreate($name) || $this->abstractFactoryCanCreate($name); - } - - /** - * Indicate whether or not the instance is immutable. - * - * @param bool $flag - */ - public function setAllowOverride($flag) - { - $this->allowOverride = (bool) $flag; - } - - /** - * Retrieve the flag indicating immutability status. - * - * @return bool - */ - public function getAllowOverride() - { - return $this->allowOverride; - } - - /** - * @psalm-param ServiceManagerConfiguration $config - * @return self - * @throws ContainerModificationsNotAllowedException If the allow - * override flag has been toggled off, and a service instance - * exists for a given service. - */ - public function configure(array $config) - { - // This is a bulk update/initial configuration, - // so we check all definitions up front. - $this->validateServiceNames($config); - - if (isset($config['services'])) { - $this->services = $config['services'] + $this->services; - } - - if (isset($config['invokables']) && ! empty($config['invokables'])) { - $newAliases = $this->createAliasesAndFactoriesForInvokables($config['invokables']); - // override existing aliases with those created by invokables to ensure - // that they are still present after merging aliases later on - $config['aliases'] = $newAliases + ($config['aliases'] ?? []); - } - - if (isset($config['factories'])) { - $this->factories = $config['factories'] + $this->factories; - } - - if (isset($config['delegators'])) { - $this->mergeDelegators($config['delegators']); - } - - if (isset($config['shared'])) { - $this->shared = $config['shared'] + $this->shared; - } - - if (! empty($config['aliases'])) { - $this->aliases = $config['aliases'] + $this->aliases; - $this->mapAliasesToTargets(); - } elseif (! $this->configured && ! empty($this->aliases)) { - $this->mapAliasesToTargets(); - } - - if (isset($config['shared_by_default'])) { - $this->sharedByDefault = $config['shared_by_default']; - } - - // If lazy service configuration was provided, reset the lazy services - // delegator factory. - if (isset($config['lazy_services']) && ! empty($config['lazy_services'])) { - /** @psalm-suppress MixedPropertyTypeCoercion */ - $this->lazyServices = ArrayUtils::merge($this->lazyServices, $config['lazy_services']); - $this->lazyServicesDelegator = null; - } - - // For abstract factories and initializers, we always directly - // instantiate them to avoid checks during service construction. - if (isset($config['abstract_factories'])) { - $abstractFactories = $config['abstract_factories']; - // $key not needed, but foreach is faster than foreach + array_values. - foreach ($abstractFactories as $key => $abstractFactory) { - $this->resolveAbstractFactoryInstance($abstractFactory); - } - } - - if (isset($config['initializers'])) { - $this->resolveInitializers($config['initializers']); - } - - $this->configured = true; - - return $this; - } - - /** - * Add an alias. - * - * @param string $alias - * @param string $target - * @throws ContainerModificationsNotAllowedException If $alias already - * exists as a service and overrides are disallowed. - */ - public function setAlias($alias, $target) - { - if (isset($this->services[$alias]) && ! $this->allowOverride) { - throw ContainerModificationsNotAllowedException::fromExistingService($alias); - } - - $this->mapAliasToTarget($alias, $target); - } - - /** - * Add an invokable class mapping. - * - * @param string $name Service name - * @param null|string $class Class to which to map; if omitted, $name is - * assumed. - * @throws ContainerModificationsNotAllowedException If $name already - * exists as a service and overrides are disallowed. - */ - public function setInvokableClass($name, $class = null) - { - if (isset($this->services[$name]) && ! $this->allowOverride) { - throw ContainerModificationsNotAllowedException::fromExistingService($name); - } - - $this->createAliasesAndFactoriesForInvokables([$name => $class ?? $name]); - } - - /** - * Specify a factory for a given service name. - * - * @param string $name Service name - * @param string|callable|Factory\FactoryInterface $factory Factory to which to map. - * phpcs:disable Generic.Files.LineLength.TooLong - * @psalm-param class-string|callable(ContainerInterface,string,array|null):object|Factory\FactoryInterface $factory - * phpcs:enable Generic.Files.LineLength.TooLong - * @return void - * @throws ContainerModificationsNotAllowedException If $name already - * exists as a service and overrides are disallowed. - */ - public function setFactory($name, $factory) - { - if (isset($this->services[$name]) && ! $this->allowOverride) { - throw ContainerModificationsNotAllowedException::fromExistingService($name); - } - - $this->factories[$name] = $factory; - } - - /** - * Create a lazy service mapping to a class. - * - * @param string $name Service name to map - * @param null|string $class Class to which to map; if not provided, $name - * will be used for the mapping. - */ - public function mapLazyService($name, $class = null) - { - $this->configure(['lazy_services' => ['class_map' => [$name => $class ?: $name]]]); - } - - /** - * Add an abstract factory for resolving services. - * - * @param string|Factory\AbstractFactoryInterface $factory Abstract factory - * instance or class name. - * @psalm-param class-string|Factory\AbstractFactoryInterface $factory - */ - public function addAbstractFactory($factory) - { - $this->resolveAbstractFactoryInstance($factory); - } - - /** - * Add a delegator for a given service. - * - * @param string $name Service name - * @param string|callable|Factory\DelegatorFactoryInterface $factory Delegator - * factory to assign. - * @psalm-param class-string - * |callable(ContainerInterface,string,callable,array|null) $factory - */ - public function addDelegator($name, $factory) - { - $this->configure(['delegators' => [$name => [$factory]]]); - } - - /** - * Add an initializer. - * - * @param string|callable|Initializer\InitializerInterface $initializer - * @psalm-param class-string - * |callable(ContainerInterface,mixed):void - * |Initializer\InitializerInterface $initializer - */ - public function addInitializer($initializer) - { - $this->configure(['initializers' => [$initializer]]); - } - - /** - * Map a service. - * - * @param string $name Service name - * @param array|object $service - * @throws ContainerModificationsNotAllowedException If $name already - * exists as a service and overrides are disallowed. - */ - public function setService($name, $service) - { - if (isset($this->services[$name]) && ! $this->allowOverride) { - throw ContainerModificationsNotAllowedException::fromExistingService($name); - } - $this->services[$name] = $service; - } - - /** - * Add a service sharing rule. - * - * @param string $name Service name - * @param bool $flag Whether or not the service should be shared. - * @throws ContainerModificationsNotAllowedException If $name already - * exists as a service and overrides are disallowed. - */ - public function setShared($name, $flag) - { - if (isset($this->services[$name]) && ! $this->allowOverride) { - throw ContainerModificationsNotAllowedException::fromExistingService($name); - } - - $this->shared[$name] = (bool) $flag; - } - - /** - * Instantiate initializers for to avoid checks during service construction. - * - * @psalm-param InitializersConfiguration $initializers - */ - private function resolveInitializers(array $initializers): void - { - foreach ($initializers as $initializer) { - if (is_string($initializer) && class_exists($initializer)) { - $initializer = new $initializer(); - } - - if (is_callable($initializer)) { - $this->initializers[] = $initializer; - continue; - } - - throw InvalidArgumentException::fromInvalidInitializer($initializer); - } - } - - /** - * Get a factory for the given service name - * - * @psalm-return (callable(ContainerInterface,string,array|null):object)|Factory\FactoryInterface - * @throws ServiceNotFoundException - */ - private function getFactory(string $name): callable - { - $factory = $this->factories[$name] ?? null; - - $lazyLoaded = false; - if (is_string($factory) && class_exists($factory)) { - $factory = new $factory(); - $lazyLoaded = true; - } - - if (is_callable($factory)) { - if ($lazyLoaded) { - $this->factories[$name] = $factory; - } - - return $factory; - } - - // Check abstract factories - foreach ($this->abstractFactories as $abstractFactory) { - if ($abstractFactory->canCreate($this->creationContext, $name)) { - return $abstractFactory; - } - } - - throw new ServiceNotFoundException(sprintf( - 'Unable to resolve service "%s" to a factory; are you certain you provided it during configuration?', - $name - )); - } - - /** - * @return object - */ - private function createDelegatorFromName(string $name, ?array $options = null) - { - $creationCallback = function () use ($name, $options) { - // Code is inlined for performance reason, instead of abstracting the creation - $factory = $this->getFactory($name); - return $factory($this->creationContext, $name, $options); - }; - - $initialCreationContext = $this->creationContext; - - foreach ($this->delegators[$name] as $index => $delegatorFactory) { - $delegatorFactory = $this->delegators[$name][$index]; - - if ($delegatorFactory === LazyServiceFactory::class) { - $delegatorFactory = $this->createLazyServiceDelegatorFactory(); - } elseif (is_string($delegatorFactory) && class_exists($delegatorFactory)) { - $delegatorFactory = new $delegatorFactory(); - } - - $this->assertCallableDelegatorFactory($delegatorFactory); - - $this->delegators[$name][$index] = $delegatorFactory; - - $creationCallback = - /** @return object */ - static fn() => $delegatorFactory($initialCreationContext, $name, $creationCallback, $options); - } - - return $creationCallback(); - } - - /** - * Create a new instance with an already resolved name - * - * This is a highly performance sensitive method, do not modify if you have not benchmarked it carefully - * - * @return object - * @throws ServiceNotFoundException If unable to resolve the service. - * @throws ServiceNotCreatedException If an exception is raised when creating a service. - * @throws ContainerExceptionInterface If any other error occurs. - */ - private function doCreate(string $resolvedName, ?array $options = null) - { - try { - if (! isset($this->delegators[$resolvedName])) { - // Let's create the service by fetching the factory - $factory = $this->getFactory($resolvedName); - $object = $factory($this->creationContext, $resolvedName, $options); - } else { - $object = $this->createDelegatorFromName($resolvedName, $options); - } - } catch (ContainerExceptionInterface $exception) { - throw $exception; - } catch (Exception $exception) { - throw new ServiceNotCreatedException(sprintf( - 'Service with name "%s" could not be created. Reason: %s', - $resolvedName, - $exception->getMessage() - ), (int) $exception->getCode(), $exception); - } - - foreach ($this->initializers as $initializer) { - $initializer($this->creationContext, $object); - } - - return $object; - } - - /** - * Create the lazy services delegator factory. - * - * Creates the lazy services delegator factory based on the lazy_services - * configuration present. - * - * @throws ServiceNotCreatedException When the lazy service class_map configuration is missing. - */ - private function createLazyServiceDelegatorFactory(): LazyServiceFactory - { - if ($this->lazyServicesDelegator) { - return $this->lazyServicesDelegator; - } - - if (! isset($this->lazyServices['class_map'])) { - throw new ServiceNotCreatedException('Missing "class_map" config key in "lazy_services"'); - } - - $factoryConfig = new ProxyConfiguration(); - - if (isset($this->lazyServices['proxies_namespace'])) { - $factoryConfig->setProxiesNamespace($this->lazyServices['proxies_namespace']); - } - - if (isset($this->lazyServices['proxies_target_dir'])) { - $factoryConfig->setProxiesTargetDir($this->lazyServices['proxies_target_dir']); - } - - if (! isset($this->lazyServices['write_proxy_files']) || ! $this->lazyServices['write_proxy_files']) { - $factoryConfig->setGeneratorStrategy(new EvaluatingGeneratorStrategy()); - } else { - $factoryConfig->setGeneratorStrategy(new FileWriterGeneratorStrategy( - new FileLocator($factoryConfig->getProxiesTargetDir()) - )); - } - - spl_autoload_register($factoryConfig->getProxyAutoloader()); - - $this->lazyServicesDelegator = new LazyServiceFactory( - new LazyLoadingValueHolderFactory($factoryConfig), - $this->lazyServices['class_map'] - ); - - return $this->lazyServicesDelegator; - } - - /** - * Merge delegators avoiding multiple same delegators for the same service. - * It works with strings and class instances. - * It's not possible to de-duple anonymous functions - * - * @psalm-param DelegatorsConfiguration $config - * @psalm-return DelegatorsConfiguration - */ - private function mergeDelegators(array $config): array - { - foreach ($config as $key => $delegators) { - if (! array_key_exists($key, $this->delegators)) { - $this->delegators[$key] = $delegators; - continue; - } - - foreach ($delegators as $delegator) { - if (! in_array($delegator, $this->delegators[$key], true)) { - $this->delegators[$key][] = $delegator; - } - } - } - - return $this->delegators; - } - - /** - * Create aliases and factories for invokable classes. - * - * If an invokable service name does not match the class it maps to, this - * creates an alias to the class (which will later be mapped as an - * invokable factory). The newly created aliases will be returned as an array. - * - * @param array $invokables - * @return array - */ - private function createAliasesAndFactoriesForInvokables(array $invokables): array - { - $newAliases = []; - - foreach ($invokables as $name => $class) { - $this->factories[$class] = Factory\InvokableFactory::class; - if ($name !== $class) { - $this->aliases[$name] = $class; - $newAliases[$name] = $class; - } - } - - return $newAliases; - } - - /** - * Determine if a service for any name provided by a service - * manager configuration(services, aliases, factories, ...) - * already exists, and if it exists, determine if is it allowed - * to get overriden. - * - * Validation in the context of this class means, that for - * a given service name we do not have a service instance - * in the cache OR override is explicitly allowed. - * - * @psalm-param ServiceManagerConfiguration $config - * @throws ContainerModificationsNotAllowedException If any - * service key is invalid. - */ - private function validateServiceNames(array $config): void - { - if ($this->allowOverride || ! $this->configured) { - return; - } - - if (isset($config['services'])) { - foreach (array_keys($config['services']) as $service) { - if (isset($this->services[$service])) { - throw ContainerModificationsNotAllowedException::fromExistingService($service); - } - } - } - - if (isset($config['aliases'])) { - foreach (array_keys($config['aliases']) as $service) { - if (isset($this->services[$service])) { - throw ContainerModificationsNotAllowedException::fromExistingService($service); - } - } - } - - if (isset($config['invokables'])) { - foreach (array_keys($config['invokables']) as $service) { - if (isset($this->services[$service])) { - throw ContainerModificationsNotAllowedException::fromExistingService($service); - } - } - } - - if (isset($config['factories'])) { - foreach (array_keys($config['factories']) as $service) { - if (isset($this->services[$service])) { - throw ContainerModificationsNotAllowedException::fromExistingService($service); - } - } - } - - if (isset($config['delegators'])) { - foreach (array_keys($config['delegators']) as $service) { - if (isset($this->services[$service])) { - throw ContainerModificationsNotAllowedException::fromExistingService($service); - } - } - } - - if (isset($config['shared'])) { - foreach (array_keys($config['shared']) as $service) { - if (isset($this->services[$service])) { - throw ContainerModificationsNotAllowedException::fromExistingService($service); - } - } - } - - if (isset($config['lazy_services']['class_map'])) { - foreach (array_keys($config['lazy_services']['class_map']) as $service) { - if (isset($this->services[$service])) { - throw ContainerModificationsNotAllowedException::fromExistingService($service); - } - } - } - } - - /** - * Assuming that the alias name is valid (see above) resolve/add it. - * - * This is done differently from bulk mapping aliases for performance reasons, as the - * algorithms for mapping a single item efficiently are different from those of mapping - * many. - */ - private function mapAliasToTarget(string $alias, string $target): void - { - // $target is either an alias or something else - // if it is an alias, resolve it - $this->aliases[$alias] = $this->aliases[$target] ?? $target; - - // a self-referencing alias indicates a cycle - if ($alias === $this->aliases[$alias]) { - throw CyclicAliasException::fromCyclicAlias($alias, $this->aliases); - } - - // finally we have to check if existing incomplete alias definitions - // exist which can get resolved by the new alias - if (in_array($alias, $this->aliases)) { - $r = array_intersect($this->aliases, [$alias]); - // found some, resolve them - foreach ($r as $name => $service) { - $this->aliases[$name] = $target; - } - } - } - - /** - * Assuming that all provided alias keys are valid resolve them. - * - * This function maps $this->aliases in place. - * - * This algorithm is an adaptated version of Tarjans Strongly - * Connected Components. Instead of returning the strongly - * connected components (i.e. cycles in our case), we throw. - * If nodes are not strongly connected (i.e. resolvable in - * our case), they get resolved. - * - * This algorithm is fast for mass updates through configure(). - * It is not appropriate if just a single alias is added. - * - * @see mapAliasToTarget above - */ - private function mapAliasesToTargets(): void - { - $tagged = []; - foreach ($this->aliases as $alias => $target) { - if (isset($tagged[$alias])) { - continue; - } - - $tCursor = $this->aliases[$alias]; - $aCursor = $alias; - if ($aCursor === $tCursor) { - throw CyclicAliasException::fromCyclicAlias($alias, $this->aliases); - } - if (! isset($this->aliases[$tCursor])) { - continue; - } - - $stack = []; - - while (isset($this->aliases[$tCursor])) { - $stack[] = $aCursor; - if ($aCursor === $this->aliases[$tCursor]) { - throw CyclicAliasException::fromCyclicAlias($alias, $this->aliases); - } - $aCursor = $tCursor; - $tCursor = $this->aliases[$tCursor]; - } - - $tagged[$aCursor] = true; - - foreach ($stack as $alias) { - if ($alias === $tCursor) { - throw CyclicAliasException::fromCyclicAlias($alias, $this->aliases); - } - $this->aliases[$alias] = $tCursor; - $tagged[$alias] = true; - } - } - } - - /** - * Instantiate abstract factories in order to avoid checks during service construction. - * - * @param string|Factory\AbstractFactoryInterface $abstractFactory - * @psalm-param class-string|Factory\AbstractFactoryInterface $abstractFactory - */ - private function resolveAbstractFactoryInstance($abstractFactory): void - { - if (is_string($abstractFactory) && class_exists($abstractFactory)) { - // Cached string factory name - if (! isset($this->cachedAbstractFactories[$abstractFactory])) { - $this->cachedAbstractFactories[$abstractFactory] = new $abstractFactory(); - } - - $abstractFactory = $this->cachedAbstractFactories[$abstractFactory]; - } - - if (! $abstractFactory instanceof Factory\AbstractFactoryInterface) { - throw InvalidArgumentException::fromInvalidAbstractFactory($abstractFactory); - } - - $abstractFactoryObjHash = spl_object_hash($abstractFactory); - $this->abstractFactories[$abstractFactoryObjHash] = $abstractFactory; - } - - /** - * Check if a static service or factory exists for the given name. - */ - private function staticServiceOrFactoryCanCreate(string $name): bool - { - if (isset($this->services[$name]) || isset($this->factories[$name])) { - return true; - } - - $resolvedName = $this->aliases[$name] ?? $name; - if ($resolvedName !== $name) { - return $this->staticServiceOrFactoryCanCreate($resolvedName); - } - - return false; - } - - /** - * Check if an abstract factory exists that can create a service for the given name. - */ - private function abstractFactoryCanCreate(string $name): bool - { - foreach ($this->abstractFactories as $abstractFactory) { - if ($abstractFactory->canCreate($this->creationContext, $name)) { - return true; - } - } - - $resolvedName = $this->aliases[$name] ?? $name; - if ($resolvedName !== $name) { - return $this->abstractFactoryCanCreate($resolvedName); - } - - return false; - } - - /** - * @psalm-param mixed $delegatorFactory - * @psalm-assert callable(ContainerInterface,string,callable():object,array|null):object $delegatorFactory - */ - private function assertCallableDelegatorFactory($delegatorFactory): void - { - if ( - $delegatorFactory instanceof Factory\DelegatorFactoryInterface - || is_callable($delegatorFactory) - ) { - return; - } - if (is_string($delegatorFactory)) { - throw new ServiceNotCreatedException(sprintf( - 'An invalid delegator factory was registered; resolved to class or function "%s"' - . ' which does not exist; please provide a valid function name or class name resolving' - . ' to an implementation of %s', - $delegatorFactory, - DelegatorFactoryInterface::class - )); - } - throw new ServiceNotCreatedException(sprintf( - 'A non-callable delegator, "%s", was provided; expected a callable or instance of "%s"', - is_object($delegatorFactory) ? $delegatorFactory::class : gettype($delegatorFactory), - DelegatorFactoryInterface::class - )); - } -} diff --git a/lib/laminas/laminas-servicemanager/src/Tool/ConfigDumper.php b/lib/laminas/laminas-servicemanager/src/Tool/ConfigDumper.php deleted file mode 100644 index 6dd6b7f6d..000000000 --- a/lib/laminas/laminas-servicemanager/src/Tool/ConfigDumper.php +++ /dev/null @@ -1,255 +0,0 @@ -validateClassName($className); - - $reflectionClass = new ReflectionClass($className); - - // class is an interface; do nothing - if ($reflectionClass->isInterface()) { - return $config; - } - - // class has no constructor, treat it as an invokable - if (! $reflectionClass->getConstructor()) { - return $this->createInvokable($config, $className); - } - - $constructorArguments = $reflectionClass->getConstructor()->getParameters(); - $constructorArguments = array_filter( - $constructorArguments, - static fn(ReflectionParameter $argument): bool => ! $argument->isOptional() - ); - - // has no required parameters, treat it as an invokable - if (empty($constructorArguments)) { - return $this->createInvokable($config, $className); - } - - $classConfig = []; - - foreach ($constructorArguments as $constructorArgument) { - $type = $constructorArgument->getType(); - $argumentType = $type instanceof ReflectionNamedType && ! $type->isBuiltin() ? $type->getName() : null; - - if ($argumentType === null) { - if ($ignoreUnresolved) { - // don't throw an exception, just return the previous config - return $config; - } - // don't throw an exception if the class is an already defined service - if ($this->container && $this->container->has($className)) { - return $config; - } - throw new InvalidArgumentException(sprintf( - 'Cannot create config for constructor argument "%s", ' - . 'it has no type hint, or non-class/interface type hint', - $constructorArgument->getName() - )); - } - $config = $this->createDependencyConfig($config, $argumentType, $ignoreUnresolved); - $classConfig[] = $argumentType; - } - - $config[ConfigAbstractFactory::class][$className] = $classConfig; - - return $config; - } - - /** - * @param string $className - * @throws InvalidArgumentException If class name is not a string or does - * not exist. - */ - private function validateClassName($className) - { - if (! is_string($className)) { - throw new InvalidArgumentException('Class name must be a string, ' . gettype($className) . ' given'); - } - - if (! class_exists($className) && ! interface_exists($className)) { - throw new InvalidArgumentException('Cannot find class or interface with name ' . $className); - } - } - - /** - * @param string $className - * @return array - */ - private function createInvokable(array $config, $className) - { - $config[ConfigAbstractFactory::class][$className] = []; - return $config; - } - - /** - * @return array - * @throws InvalidArgumentException If ConfigAbstractFactory configuration - * value is not an array. - */ - public function createFactoryMappingsFromConfig(array $config) - { - if (! array_key_exists(ConfigAbstractFactory::class, $config)) { - return $config; - } - - if (! is_array($config[ConfigAbstractFactory::class])) { - throw new InvalidArgumentException( - 'Config key for ' . ConfigAbstractFactory::class . ' should be an array, ' . gettype( - $config[ConfigAbstractFactory::class] - ) . ' given' - ); - } - - foreach ($config[ConfigAbstractFactory::class] as $className => $dependency) { - $config = $this->createFactoryMappings($config, $className); - } - return $config; - } - - /** - * @param string $className - * @return array - */ - public function createFactoryMappings(array $config, $className) - { - $this->validateClassName($className); - - if ( - array_key_exists('service_manager', $config) - && array_key_exists('factories', $config['service_manager']) - && array_key_exists($className, $config['service_manager']['factories']) - ) { - return $config; - } - - $config['service_manager']['factories'][$className] = ConfigAbstractFactory::class; - return $config; - } - - /** - * @return string - */ - public function dumpConfigFile(array $config) - { - $prepared = $this->prepareConfig($config); - return sprintf( - self::CONFIG_TEMPLATE, - static::class, - date('Y-m-d H:i:s'), - $prepared - ); - } - - /** - * @param array|Traversable $config - * @param int $indentLevel - * @return string - */ - private function prepareConfig($config, $indentLevel = 1) - { - $indent = str_repeat(' ', $indentLevel * 4); - $entries = []; - foreach ($config as $key => $value) { - $key = $this->createConfigKey($key); - $entries[] = sprintf( - '%s%s%s,', - $indent, - $key ? sprintf('%s => ', $key) : '', - $this->createConfigValue($value, $indentLevel) - ); - } - - $outerIndent = str_repeat(' ', ($indentLevel - 1) * 4); - - return sprintf( - "[\n%s\n%s]", - implode("\n", $entries), - $outerIndent - ); - } - - /** - * @param string|int|null $key - * @return null|string - */ - private function createConfigKey($key) - { - if (is_string($key) && class_exists($key)) { - return sprintf('\\%s::class', $key); - } - - if (is_int($key)) { - return null; - } - - return sprintf("'%s'", $key); - } - - /** - * @param int $indentLevel - * @return string - */ - private function createConfigValue(mixed $value, $indentLevel) - { - if (is_array($value) || $value instanceof Traversable) { - return $this->prepareConfig($value, $indentLevel + 1); - } - - if (is_string($value) && class_exists($value)) { - return sprintf('\\%s::class', $value); - } - - return var_export($value, true); - } -} diff --git a/lib/laminas/laminas-servicemanager/src/Tool/ConfigDumperCommand.php b/lib/laminas/laminas-servicemanager/src/Tool/ConfigDumperCommand.php deleted file mode 100644 index f97478686..000000000 --- a/lib/laminas/laminas-servicemanager/src/Tool/ConfigDumperCommand.php +++ /dev/null @@ -1,244 +0,0 @@ -, - * class: string, - * ignoreUnresolved: bool - * } - */ -class ConfigDumperCommand -{ - public const COMMAND_DUMP = 'dump'; - public const COMMAND_ERROR = 'error'; - public const COMMAND_HELP = 'help'; - - public const DEFAULT_SCRIPT_NAME = self::class; - - public const HELP_TEMPLATE = <<Usage: - - %s [-h|--help|help] [-i|--ignore-unresolved] - -Arguments: - - -h|--help|help This usage message - -i|--ignore-unresolved Ignore classes with unresolved direct dependencies. - Path to a config file for which to generate - configuration. If the file does not exist, it will - be created. If it does exist, it must return an - array, and the file will be updated with new - configuration. - Name of the class to reflect and for which to - generate dependency configuration. - -Reads the provided configuration file (creating it if it does not exist), -and injects it with ConfigAbstractFactory dependency configuration for -the provided class name, writing the changes back to the file. -EOH; - - private ConsoleHelper $helper; - - /** - * @param string $scriptName - */ - public function __construct(private $scriptName = self::DEFAULT_SCRIPT_NAME, ?ConsoleHelper $helper = null) - { - $this->helper = $helper ?: new ConsoleHelper(); - } - - /** - * @param array $args Argument list, minus script name - * @return int Exit status - */ - public function __invoke(array $args) - { - $arguments = $this->parseArgs($args); - - switch ($arguments->command) { - case self::COMMAND_HELP: - $this->help(); - return 0; - case self::COMMAND_ERROR: - $this->helper->writeErrorMessage($arguments->message); - $this->help(STDERR); - return 1; - case self::COMMAND_DUMP: - // fall-through - default: - break; - } - - $dumper = new ConfigDumper(); - try { - $config = $dumper->createDependencyConfig( - $arguments->config, - $arguments->class, - $arguments->ignoreUnresolved - ); - } catch (Exception\InvalidArgumentException $e) { - $this->helper->writeErrorMessage(sprintf( - 'Unable to create config for "%s": %s', - $arguments->class, - $e->getMessage() - )); - $this->help(STDERR); - return 1; - } - - file_put_contents($arguments->configFile, $dumper->dumpConfigFile($config)); - - $this->helper->writeLine(sprintf( - '[DONE] Changes written to %s', - $arguments->configFile - )); - return 0; - } - - /** - * @return object - */ - private function parseArgs(array $args) - { - if (! $args) { - return $this->createHelpArgument(); - } - - $arg1 = array_shift($args); - - if (in_array($arg1, ['-h', '--help', 'help'], true)) { - return $this->createHelpArgument(); - } - - $ignoreUnresolved = false; - if (in_array($arg1, ['-i', '--ignore-unresolved'], true)) { - $ignoreUnresolved = true; - $arg1 = array_shift($args); - } - - if (! $args) { - return $this->createErrorArgument('Missing class name'); - } - - $configFile = $arg1; - switch (file_exists($configFile)) { - case true: - $config = require $configFile; - - if (! is_array($config)) { - return $this->createErrorArgument(sprintf( - 'Configuration at path "%s" does not return an array.', - $configFile - )); - } - - break; - case false: - // fall-through - default: - if (! is_writable(dirname($configFile))) { - return $this->createErrorArgument(sprintf( - 'Cannot create configuration at path "%s"; not writable.', - $configFile - )); - } - - $config = []; - break; - } - - $class = array_shift($args); - - if (! class_exists($class)) { - return $this->createErrorArgument(sprintf( - 'Class "%s" does not exist or could not be autoloaded.', - $class - )); - } - - return $this->createArguments(self::COMMAND_DUMP, $configFile, $config, $class, $ignoreUnresolved); - } - - /** - * @param resource $resource Defaults to STDOUT - * @return void - */ - private function help($resource = STDOUT) - { - $this->helper->writeLine(sprintf( - self::HELP_TEMPLATE, - $this->scriptName - ), true, $resource); - } - - /** - * @param string $command - * @param string $configFile File from which config originates, and to - * which it will be written. - * @param array $config Parsed configuration. - * @param string $class Name of class to reflect. - * @param bool $ignoreUnresolved If to ignore classes with unresolved direct dependencies. - * @return ArgumentObject - */ - private function createArguments($command, $configFile, $config, $class, $ignoreUnresolved) - { - return (object) [ - 'command' => $command, - 'configFile' => $configFile, - 'config' => $config, - 'class' => $class, - 'ignoreUnresolved' => $ignoreUnresolved, - ]; - } - - /** - * @param string $message - * @return ErrorObject - */ - private function createErrorArgument($message) - { - return (object) [ - 'command' => self::COMMAND_ERROR, - 'message' => $message, - ]; - } - - /** - * @return HelpObject - */ - private function createHelpArgument() - { - return (object) [ - 'command' => self::COMMAND_HELP, - ]; - } -} diff --git a/lib/laminas/laminas-servicemanager/src/Tool/FactoryCreator.php b/lib/laminas/laminas-servicemanager/src/Tool/FactoryCreator.php deleted file mode 100644 index 6abcbf696..000000000 --- a/lib/laminas/laminas-servicemanager/src/Tool/FactoryCreator.php +++ /dev/null @@ -1,165 +0,0 @@ -getClassName($className); - - return sprintf( - self::FACTORY_TEMPLATE, - preg_replace('/\\\\' . $class . '$/', '', $className), - $this->createImportStatements($className), - $class, - $class, - $class, - $this->createArgumentString($className) - ); - } - - private function getClassName(string $className): string - { - return substr($className, strrpos($className, '\\') + 1); - } - - /** - * @param string $className - * @return array - */ - private function getConstructorParameters($className) - { - $reflectionClass = new ReflectionClass($className); - - if (! $reflectionClass->getConstructor()) { - return []; - } - - $constructorParameters = $reflectionClass->getConstructor()->getParameters(); - - if (empty($constructorParameters)) { - return []; - } - - $constructorParameters = array_filter( - $constructorParameters, - static function (ReflectionParameter $argument): bool { - if ($argument->isOptional()) { - return false; - } - - $type = $argument->getType(); - $class = $type instanceof ReflectionNamedType && ! $type->isBuiltin() ? $type->getName() : null; - - if (null === $class) { - throw new InvalidArgumentException(sprintf( - 'Cannot identify type for constructor argument "%s"; ' - . 'no type hint, or non-class/interface type hint', - $argument->getName() - )); - } - - return true; - } - ); - - if (empty($constructorParameters)) { - return []; - } - - return array_map(static function (ReflectionParameter $parameter): ?string { - $type = $parameter->getType(); - return $type instanceof ReflectionNamedType && ! $type->isBuiltin() ? $type->getName() : null; - }, $constructorParameters); - } - - /** - * @param string $className - * @return string - */ - private function createArgumentString($className) - { - $arguments = array_map(static fn(string $dependency): string - => sprintf('$container->get(\\%s::class)', $dependency), $this->getConstructorParameters($className)); - - switch (count($arguments)) { - case 0: - return ''; - case 1: - return array_shift($arguments); - default: - $argumentPad = str_repeat(' ', 12); - $closePad = str_repeat(' ', 8); - return sprintf( - "\n%s%s\n%s", - $argumentPad, - implode(",\n" . $argumentPad, $arguments), - $closePad - ); - } - } - - private function createImportStatements(string $className): string - { - $imports = array_merge(self::IMPORT_ALWAYS, [$className]); - sort($imports); - return implode("\n", array_map(static fn(string $import): string => sprintf('use %s;', $import), $imports)); - } -} diff --git a/lib/laminas/laminas-servicemanager/src/Tool/FactoryCreatorCommand.php b/lib/laminas/laminas-servicemanager/src/Tool/FactoryCreatorCommand.php deleted file mode 100644 index a89df1652..000000000 --- a/lib/laminas/laminas-servicemanager/src/Tool/FactoryCreatorCommand.php +++ /dev/null @@ -1,150 +0,0 @@ -Usage: - - %s [-h|--help|help] - -Arguments: - - -h|--help|help This usage message - Name of the class to reflect and for which to generate - a factory. - -Generates to STDOUT a factory for creating the specified class; this may then -be added to your application, and configured as a factory for the class. -EOH; - - private ConsoleHelper $helper; - - /** - * @param string $scriptName - */ - public function __construct(private $scriptName = self::DEFAULT_SCRIPT_NAME, ?ConsoleHelper $helper = null) - { - $this->helper = $helper ?: new ConsoleHelper(); - } - - /** - * @param array $args Argument list, minus script name - * @return int Exit status - */ - public function __invoke(array $args) - { - $arguments = $this->parseArgs($args); - - switch ($arguments->command) { - case self::COMMAND_HELP: - $this->help(); - return 0; - case self::COMMAND_ERROR: - assert(is_string($arguments->message)); - $this->helper->writeErrorMessage($arguments->message); - $this->help(STDERR); - return 1; - case self::COMMAND_DUMP: - // fall-through - default: - break; - } - - $generator = new FactoryCreator(); - assert(is_string($arguments->class)); - try { - $factory = $generator->createFactory($arguments->class); - } catch (Exception\InvalidArgumentException $e) { - $this->helper->writeErrorMessage(sprintf( - 'Unable to create factory for "%s": %s', - $arguments->class, - $e->getMessage() - )); - $this->help(STDERR); - return 1; - } - - $this->helper->write($factory, false); - return 0; - } - - /** - * @return ArgumentObject - */ - private function parseArgs(array $args) - { - if (! $args) { - return $this->createArguments(self::COMMAND_HELP); - } - - $arg1 = array_shift($args); - - if (in_array($arg1, ['-h', '--help', 'help'], true)) { - return $this->createArguments(self::COMMAND_HELP); - } - - $class = $arg1; - - if (! class_exists($class)) { - return $this->createArguments(self::COMMAND_ERROR, null, sprintf( - 'Class "%s" does not exist or could not be autoloaded.', - $class - )); - } - - return $this->createArguments(self::COMMAND_DUMP, $class); - } - - /** - * @param resource $resource Defaults to STDOUT - * @return void - */ - private function help($resource = STDOUT) - { - $this->helper->writeLine(sprintf( - self::HELP_TEMPLATE, - $this->scriptName - ), true, $resource); - } - - /** - * @param string $command - * @param string|null $class Name of class to reflect. - * @param string|null $error Error message, if any. - * @return ArgumentObject - */ - private function createArguments($command, $class = null, $error = null) - { - return (object) [ - 'command' => $command, - 'class' => $class, - 'message' => $error, - ]; - } -} diff --git a/lib/laminas/laminas-servicemanager/src/autoload.php b/lib/laminas/laminas-servicemanager/src/autoload.php deleted file mode 100644 index 76bd64e07..000000000 --- a/lib/laminas/laminas-servicemanager/src/autoload.php +++ /dev/null @@ -1,21 +0,0 @@ - ## 🇷🇺 Русским гражданам -> -> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм. -> -> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую. -> -> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!" -> -> ## 🇺🇸 To Citizens of Russia -> -> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism. -> -> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences. -> -> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!" - -`Laminas\Stdlib` is a set of components that implements general purpose utility -class for different scopes like: - -- array utilities functions; -- general messaging systems; -- string wrappers; -- etc. - ---- - -- File issues at https://github.com/laminas/laminas-stdlib/issues -- Documentation is at https://docs.laminas.dev/laminas-stdlib/ - -## Benchmarks - -We provide scripts for benchmarking laminas-stdlib using the -[PHPBench](https://github.com/phpbench/phpbench) framework; these can be -found in the `benchmark/` directory. - -To execute the benchmarks you can run the following command: - -```bash -$ vendor/bin/phpbench run --report=aggregate -``` diff --git a/lib/laminas/laminas-stdlib/composer.json b/lib/laminas/laminas-stdlib/composer.json deleted file mode 100644 index bb713ea8b..000000000 --- a/lib/laminas/laminas-stdlib/composer.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "name": "laminas/laminas-stdlib", - "description": "SPL extensions, array utilities, error handlers, and more", - "license": "BSD-3-Clause", - "keywords": [ - "laminas", - "stdlib" - ], - "homepage": "https://laminas.dev", - "support": { - "docs": "https://docs.laminas.dev/laminas-stdlib/", - "issues": "https://github.com/laminas/laminas-stdlib/issues", - "source": "https://github.com/laminas/laminas-stdlib", - "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", - "chat": "https://laminas.dev/chat", - "forum": "https://discourse.laminas.dev" - }, - "config": { - "sort-packages": true, - "platform": { - "php": "8.1.99" - }, - "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true - } - }, - "extra": { - }, - "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.5", - "phpbench/phpbench": "^1.2.15", - "phpunit/phpunit": "^10.5.8", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.20.0" - }, - "autoload": { - "psr-4": { - "Laminas\\Stdlib\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "LaminasTest\\Stdlib\\": "test/", - "LaminasBench\\Stdlib\\": "benchmark/" - } - }, - "scripts": { - "check": [ - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "static-analysis": "psalm --shepherd --stats", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" - }, - "conflict": { - "zendframework/zend-stdlib": "*" - } -} diff --git a/lib/laminas/laminas-stdlib/src/AbstractOptions.php b/lib/laminas/laminas-stdlib/src/AbstractOptions.php deleted file mode 100644 index 5db2ea95b..000000000 --- a/lib/laminas/laminas-stdlib/src/AbstractOptions.php +++ /dev/null @@ -1,200 +0,0 @@ - - */ -abstract class AbstractOptions implements ParameterObjectInterface -{ - // phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore,WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCapsProperty - - /** - * We use the __ prefix to avoid collisions with properties in - * user-implementations. - * - * @var bool - */ - protected $__strictMode__ = true; - - // phpcs:enable - - /** - * Constructor - * - * @param iterable|AbstractOptions|null $options - */ - public function __construct($options = null) - { - if (null !== $options) { - $this->setFromArray($options); - } - } - - /** - * Set one or more configuration properties - * - * @param iterable|AbstractOptions $options - * @throws Exception\InvalidArgumentException - * @return AbstractOptions Provides fluent interface - */ - public function setFromArray($options) - { - if ($options instanceof self) { - $options = $options->toArray(); - } - - if (! is_array($options) && ! $options instanceof Traversable) { - throw new Exception\InvalidArgumentException( - sprintf( - 'Parameter provided to %s must be an %s, %s or %s', - __METHOD__, - 'array', - 'Traversable', - self::class - ) - ); - } - - foreach ($options as $key => $value) { - $this->__set($key, $value); - } - - return $this; - } - - /** - * Cast to array - * - * @return array - */ - public function toArray() - { - $array = []; - - $transform = static function (array $letters): string { - /** @var list $letters */ - $letter = array_shift($letters); - return '_' . strtolower($letter); - }; - - /** @psalm-var TValue $value */ - foreach (get_object_vars($this) as $key => $value) { - if ($key === '__strictMode__') { - continue; - } - $normalizedKey = preg_replace_callback('/([A-Z])/', $transform, $key); - $array[$normalizedKey] = $value; - } - - return $array; - } - - /** - * Set a configuration property - * - * @see ParameterObject::__set() - * - * @param string $key - * @param TValue|null $value - * @throws Exception\BadMethodCallException - * @return void - */ - public function __set($key, $value) - { - $setter = 'set' . str_replace('_', '', $key); - - if (is_callable([$this, $setter])) { - $this->{$setter}($value); - - return; - } - - if ($this->__strictMode__) { - throw new Exception\BadMethodCallException(sprintf( - 'The option "%s" does not have a callable "%s" ("%s") setter method which must be defined', - $key, - 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))), - $setter - )); - } - } - - /** - * Get a configuration property - * - * @see ParameterObject::__get() - * - * @param string $key - * @throws Exception\BadMethodCallException - * @return TValue - */ - public function __get($key) - { - $getter = 'get' . str_replace('_', '', $key); - - if (is_callable([$this, $getter])) { - return $this->{$getter}(); - } - - throw new Exception\BadMethodCallException(sprintf( - 'The option "%s" does not have a callable "%s" getter method which must be defined', - $key, - 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))) - )); - } - - /** - * Test if a configuration property is null - * - * @see ParameterObject::__isset() - * - * @param string $key - * @return bool - */ - public function __isset($key) - { - $getter = 'get' . str_replace('_', '', $key); - - return method_exists($this, $getter) && null !== $this->__get($key); - } - - /** - * Set a configuration property to NULL - * - * @see ParameterObject::__unset() - * - * @param string $key - * @throws Exception\InvalidArgumentException - * @return void - */ - public function __unset($key) - { - try { - $this->__set($key, null); - } catch (Exception\BadMethodCallException $e) { - throw new Exception\InvalidArgumentException( - 'The class property $' . $key . ' cannot be unset as' - . ' NULL is an invalid value for it', - 0, - $e - ); - } - } -} diff --git a/lib/laminas/laminas-stdlib/src/ArrayObject.php b/lib/laminas/laminas-stdlib/src/ArrayObject.php deleted file mode 100644 index e0cdc7107..000000000 --- a/lib/laminas/laminas-stdlib/src/ArrayObject.php +++ /dev/null @@ -1,509 +0,0 @@ - - * @template-implements ArrayAccess - */ -#[AllowDynamicProperties] -class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable -{ - /** - * Properties of the object have their normal functionality - * when accessed as list (var_dump, foreach, etc.). - */ - public const STD_PROP_LIST = 1; - - /** - * Entries can be accessed as properties (read and write). - */ - public const ARRAY_AS_PROPS = 2; - - /** @var array */ - protected $storage; - - /** @var self::STD_PROP_LIST|self::ARRAY_AS_PROPS */ - protected $flag; - - /** @var class-string */ - protected $iteratorClass; - - /** @var list */ - protected $protectedProperties; - - /** - * @param array|object $input Object values must act like ArrayAccess - * @param self::STD_PROP_LIST|self::ARRAY_AS_PROPS $flags - * @param class-string $iteratorClass - */ - public function __construct($input = [], $flags = self::STD_PROP_LIST, $iteratorClass = ArrayIterator::class) - { - $this->setFlags($flags); - $this->storage = $input; - $this->setIteratorClass($iteratorClass); - $this->protectedProperties = array_keys(get_object_vars($this)); - } - - /** - * Returns whether the requested key exists - * - * @param TKey $key - * @return bool - */ - public function __isset(mixed $key) - { - if ($this->flag === self::ARRAY_AS_PROPS) { - return $this->offsetExists($key); - } - - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException("$key is a protected property, use a different key"); - } - - return isset($this->$key); - } - - /** - * Sets the value at the specified key to value - * - * @param TKey $key - * @param TValue $value - * @return void - */ - public function __set(mixed $key, mixed $value) - { - if ($this->flag === self::ARRAY_AS_PROPS) { - $this->offsetSet($key, $value); - return; - } - - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException("$key is a protected property, use a different key"); - } - - $this->$key = $value; - } - - /** - * Unsets the value at the specified key - * - * @param TKey $key - * @return void - */ - public function __unset(mixed $key) - { - if ($this->flag === self::ARRAY_AS_PROPS) { - $this->offsetUnset($key); - return; - } - - if (in_array($key, $this->protectedProperties)) { - throw new Exception\InvalidArgumentException("$key is a protected property, use a different key"); - } - - unset($this->$key); - } - - /** - * Returns the value at the specified key by reference - * - * @param TKey $key - * @return TValue|null - */ - public function &__get(mixed $key) - { - if ($this->flag === self::ARRAY_AS_PROPS) { - $ret = &$this->offsetGet($key); - - return $ret; - } - - if (in_array($key, $this->protectedProperties, true)) { - throw new Exception\InvalidArgumentException("$key is a protected property, use a different key"); - } - - return $this->$key; - } - - /** - * Appends the value - * - * @param TValue $value - * @return void - */ - public function append(mixed $value) - { - $this->storage[] = $value; - } - - /** - * Sort the entries by value - * - * @return void - */ - public function asort() - { - asort($this->storage); - } - - /** - * Get the number of public properties in the ArrayObject - * - * @return positive-int|0 - */ - #[ReturnTypeWillChange] - public function count() - { - return count($this->storage); - } - - /** - * Exchange the array for another one. - * - * @param array|ArrayObject|ArrayIterator|object $data - * @return array - */ - public function exchangeArray($data) - { - if (! is_array($data) && ! is_object($data)) { - throw new Exception\InvalidArgumentException( - 'Passed variable is not an array or object, using empty array instead' - ); - } - - if (is_object($data) && ($data instanceof self || $data instanceof \ArrayObject)) { - $data = $data->getArrayCopy(); - } - if (! is_array($data)) { - $data = (array) $data; - } - - $storage = $this->storage; - - $this->storage = $data; - - return $storage; - } - - /** - * Creates a copy of the ArrayObject. - * - * @return array - */ - public function getArrayCopy() - { - return $this->storage; - } - - /** - * Gets the behavior flags. - * - * @return self::STD_PROP_LIST|self::ARRAY_AS_PROPS - */ - public function getFlags() - { - return $this->flag; - } - - /** - * Create a new iterator from an ArrayObject instance - * - * @return Iterator - */ - #[ReturnTypeWillChange] - public function getIterator() - { - $class = $this->iteratorClass; - - return new $class($this->storage); - } - - /** - * Gets the iterator classname for the ArrayObject. - * - * @return class-string - */ - public function getIteratorClass() - { - return $this->iteratorClass; - } - - /** - * Sort the entries by key - * - * @return void - */ - public function ksort() - { - ksort($this->storage); - } - - /** - * Sort an array using a case insensitive "natural order" algorithm - * - * @return void - */ - public function natcasesort() - { - natcasesort($this->storage); - } - - /** - * Sort entries using a "natural order" algorithm - * - * @return void - */ - public function natsort() - { - natsort($this->storage); - } - - /** - * Returns whether the requested key exists - * - * @param TKey $key - * @return bool - */ - #[ReturnTypeWillChange] - public function offsetExists(mixed $key) - { - return isset($this->storage[$key]); - } - - /** - * {@inheritDoc} - * - * @param TKey $key - * @return TValue|null - */ - #[ReturnTypeWillChange] - public function &offsetGet(mixed $key) - { - $ret = null; - if (! $this->offsetExists($key)) { - return $ret; - } - $ret = &$this->storage[$key]; - - return $ret; - } - - /** - * Sets the value at the specified key to value - * - * @param TKey $offset - * @param TValue $value - * @return void - */ - #[ReturnTypeWillChange] - public function offsetSet(mixed $offset, mixed $value) - { - $this->storage[$offset] = $value; - } - - /** - * Unsets the value at the specified key - * - * @param TKey $offset - * @return void - */ - #[ReturnTypeWillChange] - public function offsetUnset(mixed $offset) - { - if ($this->offsetExists($offset)) { - unset($this->storage[$offset]); - } - } - - /** - * Serialize an ArrayObject - * - * @return string - */ - public function serialize() - { - return serialize($this->__serialize()); - } - - /** - * Magic method used for serializing of an instance. - * - * @return array - */ - public function __serialize() - { - return get_object_vars($this); - } - - /** - * Sets the behavior flags - * - * @param self::STD_PROP_LIST|self::ARRAY_AS_PROPS $flags - * @return void - */ - public function setFlags($flags) - { - $this->flag = $flags; - } - - /** - * Sets the iterator classname for the ArrayObject - * - * @param class-string $class - * @return void - */ - public function setIteratorClass($class) - { - if (class_exists($class)) { - $this->iteratorClass = $class; - - return; - } - - if (str_starts_with($class, '\\')) { - $class = '\\' . $class; - if (class_exists($class)) { - $this->iteratorClass = $class; - - return; - } - } - - throw new Exception\InvalidArgumentException('The iterator class does not exist'); - } - - /** - * Sort the entries with a user-defined comparison function and maintain key association - * - * @param callable(TValue, TValue): int $function - * @return void - */ - public function uasort($function) - { - if (is_callable($function)) { - uasort($this->storage, $function); - } - } - - /** - * Sort the entries by keys using a user-defined comparison function - * - * @param callable(TKey, TKey): int $function - * @return void - */ - public function uksort($function) - { - if (is_callable($function)) { - uksort($this->storage, $function); - } - } - - /** - * Unserialize an ArrayObject - * - * @param string $data - * @return void - */ - public function unserialize($data) - { - $toUnserialize = unserialize($data); - if (! is_array($toUnserialize)) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance; corrupt serialization data', - self::class - )); - } - - $this->__unserialize($toUnserialize); - } - - /** - * Magic method used to rebuild an instance. - * - * @param array $data Data array. - * @return void - */ - public function __unserialize($data) - { - $this->protectedProperties = array_keys(get_object_vars($this)); - - // Unserialize protected internal properties first - if (array_key_exists('flag', $data)) { - $this->setFlags((int) $data['flag']); - unset($data['flag']); - } - - if (array_key_exists('storage', $data)) { - if (! is_array($data['storage']) && ! is_object($data['storage'])) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance: corrupt storage data; expected array or object, received %s', - self::class, - gettype($data['storage']) - )); - } - $this->exchangeArray($data['storage']); - unset($data['storage']); - } - - if (array_key_exists('iteratorClass', $data)) { - if (! is_string($data['iteratorClass'])) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance: invalid iteratorClass; expected string, received %s', - self::class, - get_debug_type($data['iteratorClass']) - )); - } - $this->setIteratorClass($data['iteratorClass']); - unset($data['iteratorClass']); - } - - unset($data['protectedProperties']); - - // Unserialize array keys after resolving protected properties to ensure configuration is used. - foreach ($data as $k => $v) { - $this->__set($k, $v); - } - } -} diff --git a/lib/laminas/laminas-stdlib/src/ArraySerializableInterface.php b/lib/laminas/laminas-stdlib/src/ArraySerializableInterface.php deleted file mode 100644 index adb5231f2..000000000 --- a/lib/laminas/laminas-stdlib/src/ArraySerializableInterface.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ -class ArrayStack extends PhpArrayObject -{ - /** - * Retrieve iterator - * - * Retrieve an array copy of the object, reverse its order, and return an - * ArrayIterator with that reversed array. - * - * @return ArrayIterator - */ - #[ReturnTypeWillChange] - public function getIterator() - { - $array = $this->getArrayCopy(); - return new ArrayIterator(array_reverse($array)); - } -} diff --git a/lib/laminas/laminas-stdlib/src/ArrayUtils.php b/lib/laminas/laminas-stdlib/src/ArrayUtils.php deleted file mode 100644 index 7bfa20dcb..000000000 --- a/lib/laminas/laminas-stdlib/src/ArrayUtils.php +++ /dev/null @@ -1,337 +0,0 @@ - - * $list = array('a', 'b', 'c', 'd'); - * $list = array( - * 0 => 'foo', - * 1 => 'bar', - * 2 => array('foo' => 'baz'), - * ); - * - * - * @param bool $allowEmpty Is an empty list a valid list? - * @return bool - */ - public static function isList(mixed $value, $allowEmpty = false) - { - if (! is_array($value)) { - return false; - } - - if (! $value) { - return $allowEmpty; - } - - return array_values($value) === $value; - } - - /** - * Test whether an array is a hash table. - * - * An array is a hash table if: - * - * 1. Contains one or more non-integer keys, or - * 2. Integer keys are non-continuous or misaligned (not starting with 0) - * - * For example: - * - * $hash = array( - * 'foo' => 15, - * 'bar' => false, - * ); - * $hash = array( - * 1995 => 'Birth of PHP', - * 2009 => 'PHP 5.3.0', - * 2012 => 'PHP 5.4.0', - * ); - * $hash = array( - * 'formElement, - * 'options' => array( 'debug' => true ), - * ); - * - * - * @param bool $allowEmpty Is an empty array() a valid hash table? - * @return bool - */ - public static function isHashTable(mixed $value, $allowEmpty = false) - { - if (! is_array($value)) { - return false; - } - - if (! $value) { - return $allowEmpty; - } - - return array_values($value) !== $value; - } - - /** - * Checks if a value exists in an array. - * - * Due to "foo" == 0 === TRUE with in_array when strict = false, an option - * has been added to prevent this. When $strict = 0/false, the most secure - * non-strict check is implemented. if $strict = -1, the default in_array - * non-strict behaviour is used. - * - * @deprecated This method will be removed in version 4.0 of this component - * - * @param array $haystack - * @param int|bool $strict - * @return bool - */ - public static function inArray(mixed $needle, array $haystack, $strict = false) - { - if ((bool) $strict === false) { - if (is_int($needle) || is_float($needle)) { - $needle = (string) $needle; - } - if (is_string($needle)) { - foreach ($haystack as &$h) { - if (is_int($h) || is_float($h)) { - $h = (string) $h; - } - } - } - } - - return in_array($needle, $haystack, (bool) $strict); - } - - /** - * Converts an iterator to an array. The $recursive flag, on by default, - * hints whether or not you want to do so recursively. - * - * @template TKey - * @template TValue - * @param iterable $iterator The array or Traversable object to convert - * @param bool $recursive Recursively check all nested structures - * @throws Exception\InvalidArgumentException If $iterator is not an array or a Traversable object. - * @return array - */ - public static function iteratorToArray($iterator, $recursive = true) - { - /** @psalm-suppress DocblockTypeContradiction */ - if (! is_array($iterator) && ! $iterator instanceof Traversable) { - throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable object'); - } - - if (! $recursive) { - if (is_array($iterator)) { - return $iterator; - } - - return iterator_to_array($iterator); - } - - if ( - is_object($iterator) - && ! $iterator instanceof Iterator - && method_exists($iterator, 'toArray') - ) { - /** @psalm-var array $array */ - $array = $iterator->toArray(); - - return $array; - } - - $array = []; - foreach ($iterator as $key => $value) { - if (is_scalar($value)) { - $array[$key] = $value; - continue; - } - - if ($value instanceof Traversable) { - $array[$key] = static::iteratorToArray($value, $recursive); - continue; - } - - if (is_array($value)) { - $array[$key] = static::iteratorToArray($value, $recursive); - continue; - } - - $array[$key] = $value; - } - - /** @psalm-var array $array */ - - return $array; - } - - /** - * Merge two arrays together. - * - * If an integer key exists in both arrays and preserveNumericKeys is false, the value - * from the second array will be appended to the first array. If both values are arrays, they - * are merged together, else the value of the second array overwrites the one of the first array. - * - * @param array $a - * @param array $b - * @param bool $preserveNumericKeys - * @return array - */ - public static function merge(array $a, array $b, $preserveNumericKeys = false) - { - foreach ($b as $key => $value) { - if ($value instanceof MergeReplaceKeyInterface) { - $a[$key] = $value->getData(); - } elseif (isset($a[$key]) || array_key_exists($key, $a)) { - if ($value instanceof MergeRemoveKey) { - unset($a[$key]); - } elseif (! $preserveNumericKeys && is_int($key)) { - $a[] = $value; - } elseif (is_array($value) && is_array($a[$key])) { - $a[$key] = static::merge($a[$key], $value, $preserveNumericKeys); - } else { - $a[$key] = $value; - } - } else { - if (! $value instanceof MergeRemoveKey) { - $a[$key] = $value; - } - } - } - - return $a; - } - - /** - * @deprecated Since 3.2.0; use the native array_filter methods - * - * @param callable $callback - * @param null|int $flag - * @return array - * @throws Exception\InvalidArgumentException - */ - public static function filter(array $data, $callback, $flag = null) - { - if (! is_callable($callback)) { - throw new Exception\InvalidArgumentException(sprintf( - 'Second parameter of %s must be callable', - __METHOD__ - )); - } - - return array_filter($data, $callback, $flag ?? 0); - } -} diff --git a/lib/laminas/laminas-stdlib/src/ArrayUtils/MergeRemoveKey.php b/lib/laminas/laminas-stdlib/src/ArrayUtils/MergeRemoveKey.php deleted file mode 100644 index bde0b25ae..000000000 --- a/lib/laminas/laminas-stdlib/src/ArrayUtils/MergeRemoveKey.php +++ /dev/null @@ -1,9 +0,0 @@ -data; - } -} diff --git a/lib/laminas/laminas-stdlib/src/ArrayUtils/MergeReplaceKeyInterface.php b/lib/laminas/laminas-stdlib/src/ArrayUtils/MergeReplaceKeyInterface.php deleted file mode 100644 index 47243fc24..000000000 --- a/lib/laminas/laminas-stdlib/src/ArrayUtils/MergeReplaceKeyInterface.php +++ /dev/null @@ -1,16 +0,0 @@ -message`, - * `message`) - * - Write output to a specified stream, optionally with colorization. - * - Write a line of output to a specified stream, optionally with - * colorization, using the system EOL sequence.. - * - Write an error message to STDERR. - * - * Colorization will only occur when expected sequences are discovered, and - * then, only if the console terminal allows it. - * - * Essentially, provides the bare minimum to allow you to provide messages to - * the current console. - */ -class ConsoleHelper -{ - public const COLOR_GREEN = "\033[32m"; - public const COLOR_RED = "\033[31m"; - public const COLOR_RESET = "\033[0m"; - - public const HIGHLIGHT_INFO = 'info'; - public const HIGHLIGHT_ERROR = 'error'; - - /** @psalm-var array */ - private array $highlightMap = [ - self::HIGHLIGHT_INFO => self::COLOR_GREEN, - self::HIGHLIGHT_ERROR => self::COLOR_RED, - ]; - - /** @var string Exists only for testing. */ - private string $eol = PHP_EOL; - - /** @var resource Exists only for testing. */ - private $stderr = STDERR; - - private bool $supportsColor; - - /** - * @param resource $resource - */ - public function __construct($resource = STDOUT) - { - $this->supportsColor = $this->detectColorCapabilities($resource); - } - - /** - * Colorize a string for use with the terminal. - * - * Takes strings formatted as `string` and formats them per the - * $highlightMap; if color support is disabled, simply removes the formatting - * tags. - * - * @param string $string - * @return string - */ - public function colorize($string) - { - $reset = $this->supportsColor ? self::COLOR_RESET : ''; - foreach ($this->highlightMap as $key => $color) { - $pattern = sprintf('#<%s>(.*?)#s', $key, $key); - $color = $this->supportsColor ? $color : ''; - $string = preg_replace($pattern, $color . '$1' . $reset, $string); - } - return $string; - } - - /** - * @param string $string - * @param bool $colorize Whether or not to colorize the string - * @param resource $resource Defaults to STDOUT - * @return void - */ - public function write($string, $colorize = true, $resource = STDOUT) - { - if ($colorize) { - $string = $this->colorize($string); - } - - $string = $this->formatNewlines($string); - - fwrite($resource, $string); - } - - /** - * @param string $string - * @param bool $colorize Whether or not to colorize the line - * @param resource $resource Defaults to STDOUT - * @return void - */ - public function writeLine($string, $colorize = true, $resource = STDOUT) - { - $this->write($string . $this->eol, $colorize, $resource); - } - - /** - * Emit an error message. - * - * Wraps the message in ``, and passes it to `writeLine()`, - * using STDERR as the resource; emits an additional empty line when done, - * also to STDERR. - * - * @param string $message - * @return void - */ - public function writeErrorMessage($message) - { - $this->writeLine(sprintf('%s', $message), true, $this->stderr); - $this->writeLine('', false, $this->stderr); - } - - /** - * @param resource $resource - * @return bool - */ - private function detectColorCapabilities($resource = STDOUT) - { - if ('\\' === DIRECTORY_SEPARATOR) { - // Windows - return false !== getenv('ANSICON') - || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM'); - } - - return function_exists('posix_isatty') && posix_isatty($resource); - } - - /** - * Ensure newlines are appropriate for the current terminal. - * - * @param string $string - * @return string - */ - private function formatNewlines($string) - { - $string = str_replace($this->eol, "\0PHP_EOL\0", $string); - $string = preg_replace("/(\r\n|\n|\r)/", $this->eol, $string); - return str_replace("\0PHP_EOL\0", $this->eol, $string); - } -} diff --git a/lib/laminas/laminas-stdlib/src/DispatchableInterface.php b/lib/laminas/laminas-stdlib/src/DispatchableInterface.php deleted file mode 100644 index a9b325a67..000000000 --- a/lib/laminas/laminas-stdlib/src/DispatchableInterface.php +++ /dev/null @@ -1,15 +0,0 @@ - - */ - protected static $stack = []; - - /** - * Check if this error handler is active - * - * @return bool - */ - public static function started() - { - return (bool) static::getNestedLevel(); - } - - /** - * Get the current nested level - * - * @return int - */ - public static function getNestedLevel() - { - return count(static::$stack); - } - - /** - * Starting the error handler - * - * @param int $errorLevel - * @return void - */ - public static function start($errorLevel = E_WARNING) - { - if (! static::$stack) { - set_error_handler([static::class, 'addError'], $errorLevel); - } - - static::$stack[] = null; - } - - /** - * Stopping the error handler - * - * @param bool $throw Throw the ErrorException if any - * @return null|ErrorException - * @throws ErrorException If an error has been caught and $throw is true. - */ - public static function stop($throw = false) - { - $errorException = null; - - if (static::$stack) { - $errorException = array_pop(static::$stack); - - if (! static::$stack) { - restore_error_handler(); - } - - if ($errorException && $throw) { - throw $errorException; - } - } - - return $errorException; - } - - /** - * Stop all active handler - * - * @return void - */ - public static function clean() - { - if (static::$stack) { - restore_error_handler(); - } - - static::$stack = []; - } - - /** - * Add an error to the stack - * - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param int $errline - * @return void - */ - public static function addError($errno, $errstr = '', $errfile = '', $errline = 0) - { - $stack = &static::$stack[count(static::$stack) - 1]; - $stack = new ErrorException($errstr, 0, $errno, $errfile, $errline, $stack); - } -} diff --git a/lib/laminas/laminas-stdlib/src/Exception/BadMethodCallException.php b/lib/laminas/laminas-stdlib/src/Exception/BadMethodCallException.php deleted file mode 100644 index a62b91717..000000000 --- a/lib/laminas/laminas-stdlib/src/Exception/BadMethodCallException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class FastPriorityQueue implements Iterator, Countable, Serializable -{ - public const EXTR_DATA = PhpSplPriorityQueue::EXTR_DATA; - public const EXTR_PRIORITY = PhpSplPriorityQueue::EXTR_PRIORITY; - public const EXTR_BOTH = PhpSplPriorityQueue::EXTR_BOTH; - - /** @var self::EXTR_* */ - protected $extractFlag = self::EXTR_DATA; - - /** - * Elements of the queue, divided by priorities - * - * @var array> - */ - protected $values = []; - - /** - * Array of priorities - * - * @var array - */ - protected $priorities = []; - - /** - * Array of priorities used for the iteration - * - * @var array - */ - protected $subPriorities = []; - - /** - * Max priority - * - * @var int|null - */ - protected $maxPriority; - - /** - * Total number of elements in the queue - * - * @var int - */ - protected $count = 0; - - /** - * Index of the current element in the queue - * - * @var int - */ - protected $index = 0; - - /** - * Sub index of the current element in the same priority level - * - * @var int - */ - protected $subIndex = 0; - - public function __serialize(): array - { - $clone = clone $this; - $clone->setExtractFlags(self::EXTR_BOTH); - - $data = []; - foreach ($clone as $item) { - $data[] = $item; - } - - return $data; - } - - public function __unserialize(array $data): void - { - foreach ($data as $item) { - $this->insert($item['data'], $item['priority']); - } - } - - /** - * Insert an element in the queue with a specified priority - * - * @param TValue $value - * @param int $priority - * @return void - */ - public function insert(mixed $value, $priority) - { - if (! is_int($priority)) { - throw new Exception\InvalidArgumentException('The priority must be an integer'); - } - $this->values[$priority][] = $value; - if (! isset($this->priorities[$priority])) { - $this->priorities[$priority] = $priority; - $this->maxPriority = $this->maxPriority === null ? $priority : max($priority, $this->maxPriority); - } - ++$this->count; - } - - /** - * Extract an element in the queue according to the priority and the - * order of insertion - * - * @return TValue|int|array{data: TValue, priority: int}|false - */ - public function extract() - { - if (! $this->valid()) { - return false; - } - $value = $this->current(); - $this->nextAndRemove(); - return $value; - } - - /** - * Remove an item from the queue - * - * This is different than {@link extract()}; its purpose is to dequeue an - * item. - * - * Note: this removes the first item matching the provided item found. If - * the same item has been added multiple times, it will not remove other - * instances. - * - * @return bool False if the item was not found, true otherwise. - */ - public function remove(mixed $datum) - { - $currentIndex = $this->index; - $currentSubIndex = $this->subIndex; - $currentPriority = $this->maxPriority; - - $this->rewind(); - while ($this->valid()) { - if (current($this->values[$this->maxPriority]) === $datum) { - $index = key($this->values[$this->maxPriority]); - unset($this->values[$this->maxPriority][$index]); - - // The `next()` method advances the internal array pointer, so we need to use the `reset()` function, - // otherwise we would lose all elements before the place the pointer points. - reset($this->values[$this->maxPriority]); - - $this->index = $currentIndex; - $this->subIndex = $currentSubIndex; - - // If the array is empty we need to destroy the unnecessary priority, - // otherwise we would end up with an incorrect value of `$this->count` - // {@see \Laminas\Stdlib\FastPriorityQueue::nextAndRemove()}. - if (empty($this->values[$this->maxPriority])) { - unset($this->values[$this->maxPriority]); - unset($this->priorities[$this->maxPriority]); - if ($this->maxPriority === $currentPriority) { - $this->subIndex = 0; - } - } - - $this->maxPriority = empty($this->priorities) ? null : max($this->priorities); - --$this->count; - return true; - } - $this->next(); - } - return false; - } - - /** - * Get the total number of elements in the queue - * - * @return int - */ - #[ReturnTypeWillChange] - public function count() - { - return $this->count; - } - - /** - * Get the current element in the queue - * - * @return TValue|int|array{data: TValue|false, priority: int|null}|false - */ - #[ReturnTypeWillChange] - public function current() - { - switch ($this->extractFlag) { - case self::EXTR_DATA: - return current($this->values[$this->maxPriority]); - case self::EXTR_PRIORITY: - return $this->maxPriority; - case self::EXTR_BOTH: - return [ - 'data' => current($this->values[$this->maxPriority]), - 'priority' => $this->maxPriority, - ]; - } - } - - /** - * Get the index of the current element in the queue - * - * @return int - */ - #[ReturnTypeWillChange] - public function key() - { - return $this->index; - } - - /** - * Set the iterator pointer to the next element in the queue - * removing the previous element - * - * @return void - */ - protected function nextAndRemove() - { - $key = key($this->values[$this->maxPriority]); - - if (false === next($this->values[$this->maxPriority])) { - unset($this->priorities[$this->maxPriority]); - unset($this->values[$this->maxPriority]); - $this->maxPriority = empty($this->priorities) ? null : max($this->priorities); - $this->subIndex = -1; - } else { - unset($this->values[$this->maxPriority][$key]); - } - ++$this->index; - ++$this->subIndex; - --$this->count; - } - - /** - * Set the iterator pointer to the next element in the queue - * without removing the previous element - */ - #[ReturnTypeWillChange] - public function next() - { - if (false === next($this->values[$this->maxPriority])) { - unset($this->subPriorities[$this->maxPriority]); - reset($this->values[$this->maxPriority]); - $this->maxPriority = empty($this->subPriorities) ? null : max($this->subPriorities); - $this->subIndex = -1; - } - ++$this->index; - ++$this->subIndex; - } - - /** - * Check if the current iterator is valid - * - * @return bool - */ - #[ReturnTypeWillChange] - public function valid() - { - return isset($this->values[$this->maxPriority]); - } - - /** - * Rewind the current iterator - */ - #[ReturnTypeWillChange] - public function rewind() - { - $this->subPriorities = $this->priorities; - $this->maxPriority = empty($this->priorities) ? 0 : max($this->priorities); - $this->index = 0; - $this->subIndex = 0; - } - - /** - * Serialize to an array - * - * Array will be priority => data pairs - * - * @return list - */ - public function toArray() - { - $array = []; - foreach (clone $this as $item) { - $array[] = $item; - } - return $array; - } - - /** - * Serialize - * - * @return string - */ - public function serialize() - { - return serialize($this->__serialize()); - } - - /** - * Deserialize - * - * @param string $data - * @return void - */ - public function unserialize($data) - { - $toUnserialize = unserialize($data); - if (! is_array($toUnserialize)) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance; corrupt serialization data', - self::class - )); - } - - $this->__unserialize($toUnserialize); - } - - /** - * Set the extract flag - * - * @param self::EXTR_* $flag - * @return void - */ - public function setExtractFlags($flag) - { - $this->extractFlag = match ($flag) { - self::EXTR_DATA, self::EXTR_PRIORITY, self::EXTR_BOTH => $flag, - default => throw new Exception\InvalidArgumentException("The extract flag specified is not valid"), - }; - } - - /** - * Check if the queue is empty - * - * @return bool - */ - public function isEmpty() - { - return empty($this->values); - } - - /** - * Does the queue contain the given datum? - * - * @return bool - */ - public function contains(mixed $datum) - { - foreach ($this->values as $values) { - if (in_array($datum, $values)) { - return true; - } - } - return false; - } - - /** - * Does the queue have an item with the given priority? - * - * @param int $priority - * @return bool - */ - public function hasPriority($priority) - { - return isset($this->values[$priority]); - } -} diff --git a/lib/laminas/laminas-stdlib/src/Glob.php b/lib/laminas/laminas-stdlib/src/Glob.php deleted file mode 100644 index 5b5be710d..000000000 --- a/lib/laminas/laminas-stdlib/src/Glob.php +++ /dev/null @@ -1,226 +0,0 @@ - GLOB_MARK, - self::GLOB_NOSORT => GLOB_NOSORT, - self::GLOB_NOCHECK => GLOB_NOCHECK, - self::GLOB_NOESCAPE => GLOB_NOESCAPE, - self::GLOB_BRACE => defined('GLOB_BRACE') ? GLOB_BRACE : 0, - self::GLOB_ONLYDIR => GLOB_ONLYDIR, - self::GLOB_ERR => GLOB_ERR, - ]; - - $globFlags = 0; - - foreach ($flagMap as $internalFlag => $globFlag) { - if ($flags & $internalFlag) { - $globFlags |= $globFlag; - } - } - } else { - $globFlags = 0; - } - - ErrorHandler::start(); - $res = glob($pattern, $globFlags); - $err = ErrorHandler::stop(); - if ($res === false) { - throw new Exception\RuntimeException("glob('{$pattern}', {$globFlags}) failed", 0, $err); - } - return $res; - } - - /** - * Expand braces manually, then use the system glob. - * - * @param string $pattern - * @param int $flags - * @return array - * @throws Exception\RuntimeException - */ - protected static function fallbackGlob($pattern, $flags) - { - if (! self::flagsIsEqualTo($flags, self::GLOB_BRACE)) { - return static::systemGlob($pattern, $flags); - } - - $flags &= ~self::GLOB_BRACE; - $length = strlen($pattern); - $paths = []; - - if ($flags & self::GLOB_NOESCAPE) { - $begin = strpos($pattern, '{'); - } else { - $begin = 0; - - while (true) { - if ($begin === $length) { - $begin = false; - break; - } elseif ($pattern[$begin] === '\\' && ($begin + 1) < $length) { - $begin++; - } elseif ($pattern[$begin] === '{') { - break; - } - - $begin++; - } - } - - if ($begin === false) { - return static::systemGlob($pattern, $flags); - } - - $next = static::nextBraceSub($pattern, $begin + 1, $flags); - - if ($next === null) { - return static::systemGlob($pattern, $flags); - } - - $rest = $next; - - while ($pattern[$rest] !== '}') { - $rest = static::nextBraceSub($pattern, $rest + 1, $flags); - - if ($rest === null) { - return static::systemGlob($pattern, $flags); - } - } - - $p = $begin + 1; - - while (true) { - $subPattern = substr($pattern, 0, $begin) - . substr($pattern, $p, $next - $p) - . substr($pattern, $rest + 1); - - $result = static::fallbackGlob($subPattern, $flags | self::GLOB_BRACE); - - if ($result) { - $paths = array_merge($paths, $result); - } - - if ($pattern[$next] === '}') { - break; - } - - $p = $next + 1; - $next = static::nextBraceSub($pattern, $p, $flags); - } - - return array_unique($paths); - } - - /** - * Find the end of the sub-pattern in a brace expression. - * - * @param string $pattern - * @param int $begin - * @param int $flags - * @return int|null - */ - protected static function nextBraceSub($pattern, $begin, $flags) - { - $length = strlen($pattern); - $depth = 0; - $current = $begin; - - while ($current < $length) { - $flagsEqualsNoEscape = self::flagsIsEqualTo($flags, self::GLOB_NOESCAPE); - - if ($flagsEqualsNoEscape && $pattern[$current] === '\\') { - if (++$current === $length) { - break; - } - - $current++; - } else { - if ( - ($pattern[$current] === '}' && $depth-- === 0) - || ($pattern[$current] === ',' && $depth === 0) - ) { - break; - } elseif ($pattern[$current++] === '{') { - $depth++; - } - } - } - - return $current < $length ? $current : null; - } - - /** @internal */ - public static function flagsIsEqualTo(int $flags, int $otherFlags): bool - { - return (bool) ($flags & $otherFlags); - } -} diff --git a/lib/laminas/laminas-stdlib/src/Guard/AllGuardsTrait.php b/lib/laminas/laminas-stdlib/src/Guard/AllGuardsTrait.php deleted file mode 100644 index b5abe5a62..000000000 --- a/lib/laminas/laminas-stdlib/src/Guard/AllGuardsTrait.php +++ /dev/null @@ -1,15 +0,0 @@ -metadata[$spec] = $value; - return $this; - } - if (! is_array($spec) && ! $spec instanceof Traversable) { - throw new Exception\InvalidArgumentException(sprintf( - 'Expected a string, array, or Traversable argument in first position; received "%s"', - get_debug_type($spec) - )); - } - foreach ($spec as $key => $value) { - $this->metadata[$key] = $value; - } - return $this; - } - - /** - * Retrieve all metadata or a single metadatum as specified by key - * - * @param null|string|int $key - * @param null|mixed $default - * @throws Exception\InvalidArgumentException - * @return mixed - */ - public function getMetadata($key = null, $default = null) - { - if (null === $key) { - return $this->metadata; - } - - if (! is_scalar($key)) { - throw new Exception\InvalidArgumentException('Non-scalar argument provided for key'); - } - - if (array_key_exists($key, $this->metadata)) { - return $this->metadata[$key]; - } - - return $default; - } - - /** - * Set message content - * - * @param mixed $value - * @return Message - */ - public function setContent($value) - { - $this->content = $value; - return $this; - } - - /** - * Get message content - * - * @return mixed - */ - public function getContent() - { - return $this->content; - } - - /** - * @return string - */ - public function toString() - { - $request = ''; - foreach ($this->getMetadata() as $key => $value) { - $request .= sprintf( - "%s: %s\r\n", - (string) $key, - (string) $value - ); - } - $request .= "\r\n" . $this->getContent(); - return $request; - } -} diff --git a/lib/laminas/laminas-stdlib/src/MessageInterface.php b/lib/laminas/laminas-stdlib/src/MessageInterface.php deleted file mode 100644 index 71a482081..000000000 --- a/lib/laminas/laminas-stdlib/src/MessageInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @template-implements ParametersInterface - */ -class Parameters extends PhpArrayObject implements ParametersInterface -{ - /** - * Constructor - * - * Enforces that we have an array, and enforces parameter access to array - * elements. - * - * @param array|null $values - */ - public function __construct(?array $values = null) - { - if (null === $values) { - $values = []; - } - parent::__construct($values, ArrayObject::ARRAY_AS_PROPS); - } - - /** - * Populate from native PHP array - * - * @param array $values - * @return void - */ - public function fromArray(array $values) - { - $this->exchangeArray($values); - } - - /** - * Populate from query string - * - * @param string $string - * @return void - */ - public function fromString($string) - { - $array = []; - parse_str($string, $array); - $this->fromArray($array); - } - - /** - * Serialize to native PHP array - * - * @return array - */ - public function toArray() - { - return $this->getArrayCopy(); - } - - /** - * Serialize to query string - * - * @return string - */ - public function toString() - { - return http_build_query($this->toArray()); - } - - /** - * Retrieve by key - * - * Returns null if the key does not exist. - * - * @param TKey $name - * @return TValue|null - */ - #[ReturnTypeWillChange] - public function offsetGet($name) - { - if ($this->offsetExists($name)) { - return parent::offsetGet($name); - } - - return null; - } - - /** - * @template TDefault - * @param TKey $name - * @param TDefault $default optional default value - * @return TValue|TDefault|null - */ - public function get($name, $default = null) - { - if ($this->offsetExists($name)) { - return parent::offsetGet($name); - } - return $default; - } - - /** - * @param TKey $name - * @param TValue $value - * @return $this - */ - public function set($name, $value) - { - $this[$name] = $value; - return $this; - } -} diff --git a/lib/laminas/laminas-stdlib/src/ParametersInterface.php b/lib/laminas/laminas-stdlib/src/ParametersInterface.php deleted file mode 100644 index 9b9a0c4cd..000000000 --- a/lib/laminas/laminas-stdlib/src/ParametersInterface.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @template-extends Traversable - */ -interface ParametersInterface extends ArrayAccess, Countable, Serializable, Traversable -{ - /** - * Constructor - * - * @param array|null $values - */ - public function __construct(?array $values = null); - - /** - * From array - * - * Allow deserialization from standard array - * - * @param array $values - * @return mixed - */ - public function fromArray(array $values); - - /** - * From string - * - * Allow deserialization from raw body; e.g., for PUT requests - * - * @param string $string - * @return mixed - */ - public function fromString($string); - - /** - * To array - * - * Allow serialization back to standard array - * - * @return array - */ - public function toArray(); - - /** - * To string - * - * Allow serialization to query format; e.g., for PUT or POST requests - * - * @return string - */ - public function toString(); - - /** - * @param TKey $name - * @param TValue|null $default - * @return mixed - */ - public function get($name, $default = null); - - /** - * @param TKey $name - * @param TValue $value - * @return ParametersInterface - */ - public function set($name, $value); -} diff --git a/lib/laminas/laminas-stdlib/src/PriorityList.php b/lib/laminas/laminas-stdlib/src/PriorityList.php deleted file mode 100644 index 8e2c6e533..000000000 --- a/lib/laminas/laminas-stdlib/src/PriorityList.php +++ /dev/null @@ -1,287 +0,0 @@ - - */ -class PriorityList implements Iterator, Countable -{ - public const EXTR_DATA = 0x00000001; - public const EXTR_PRIORITY = 0x00000002; - public const EXTR_BOTH = 0x00000003; - - /** - * Internal list of all items. - * - * @var array - */ - protected $items = []; - - /** - * Serial assigned to items to preserve LIFO. - * - * @var positive-int|0 - */ - protected $serial = 0; - - // phpcs:disable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCapsProperty - - /** - * Serial order mode - * - * @var integer - */ - protected $isLIFO = 1; - - // phpcs:enable - - /** - * Internal counter to avoid usage of count(). - * - * @var int - */ - protected $count = 0; - - /** - * Whether the list was already sorted. - * - * @var bool - */ - protected $sorted = false; - - /** - * Insert a new item. - * - * @param TKey $name - * @param TValue $value - * @param int $priority - * @return void - */ - public function insert($name, mixed $value, $priority = 0) - { - if (! isset($this->items[$name])) { - $this->count++; - } - - $this->sorted = false; - - $this->items[$name] = [ - 'data' => $value, - 'priority' => (int) $priority, - 'serial' => $this->serial++, - ]; - } - - /** - * @param TKey $name - * @param int $priority - * @return $this - * @throws Exception - */ - public function setPriority($name, $priority) - { - if (! isset($this->items[$name])) { - throw new Exception("item $name not found"); - } - - $this->items[$name]['priority'] = (int) $priority; - $this->sorted = false; - - return $this; - } - - /** - * Remove a item. - * - * @param TKey $name - * @return void - */ - public function remove($name) - { - if (isset($this->items[$name])) { - $this->count--; - } - - unset($this->items[$name]); - } - - /** - * Remove all items. - * - * @return void - */ - public function clear() - { - $this->items = []; - $this->serial = 0; - $this->count = 0; - $this->sorted = false; - } - - /** - * Get a item. - * - * @param TKey $name - * @return TValue|null - */ - public function get($name) - { - if (! isset($this->items[$name])) { - return; - } - - return $this->items[$name]['data']; - } - - /** - * Sort all items. - * - * @return void - */ - protected function sort() - { - if (! $this->sorted) { - uasort($this->items, [$this, 'compare']); - $this->sorted = true; - } - } - - /** - * Compare the priority of two items. - * - * @param array $item1, - * @return int - */ - protected function compare(array $item1, array $item2) - { - return $item1['priority'] === $item2['priority'] - ? ($item1['serial'] > $item2['serial'] ? -1 : 1) * $this->isLIFO - : ($item1['priority'] > $item2['priority'] ? -1 : 1); - } - - /** - * Get/Set serial order mode - * - * @param bool|null $flag - * @return bool - */ - public function isLIFO($flag = null) - { - if ($flag !== null) { - $isLifo = $flag === true ? 1 : -1; - - if ($isLifo !== $this->isLIFO) { - $this->isLIFO = $isLifo; - $this->sorted = false; - } - } - - return 1 === $this->isLIFO; - } - - /** - * {@inheritDoc} - */ - #[ReturnTypeWillChange] - public function rewind() - { - $this->sort(); - reset($this->items); - } - - /** - * {@inheritDoc} - */ - #[ReturnTypeWillChange] - public function current() - { - $this->sorted || $this->sort(); - $node = current($this->items); - - return $node ? $node['data'] : false; - } - - /** - * {@inheritDoc} - */ - #[ReturnTypeWillChange] - public function key() - { - $this->sorted || $this->sort(); - return key($this->items); - } - - /** - * {@inheritDoc} - */ - #[ReturnTypeWillChange] - public function next() - { - $node = next($this->items); - - return $node ? $node['data'] : false; - } - - /** - * {@inheritDoc} - */ - #[ReturnTypeWillChange] - public function valid() - { - return current($this->items) !== false; - } - - /** - * @return self - */ - public function getIterator() - { - return clone $this; - } - - /** - * {@inheritDoc} - */ - #[ReturnTypeWillChange] - public function count() - { - return $this->count; - } - - /** - * Return list as array - * - * @param int $flag - * @return array - */ - public function toArray($flag = self::EXTR_DATA) - { - $this->sort(); - - if ($flag === self::EXTR_BOTH) { - return $this->items; - } - - return array_map( - static fn($item) => $flag === self::EXTR_PRIORITY ? $item['priority'] : $item['data'], - $this->items - ); - } -} diff --git a/lib/laminas/laminas-stdlib/src/PriorityQueue.php b/lib/laminas/laminas-stdlib/src/PriorityQueue.php deleted file mode 100644 index b42580236..000000000 --- a/lib/laminas/laminas-stdlib/src/PriorityQueue.php +++ /dev/null @@ -1,379 +0,0 @@ - - */ -class PriorityQueue implements Countable, IteratorAggregate, Serializable -{ - public const EXTR_DATA = 0x00000001; - public const EXTR_PRIORITY = 0x00000002; - public const EXTR_BOTH = 0x00000003; - - /** - * Inner queue class to use for iteration - * - * @var class-string<\SplPriorityQueue> - */ - protected $queueClass = SplPriorityQueue::class; - - /** - * Actual items aggregated in the priority queue. Each item is an array - * with keys "data" and "priority". - * - * @var list - */ - protected $items = []; - - /** - * Inner queue object - * - * @var \SplPriorityQueue|null - */ - protected $queue; - - /** - * Insert an item into the queue - * - * Priority defaults to 1 (low priority) if none provided. - * - * @param TValue $data - * @param TPriority $priority - * @return $this - */ - public function insert($data, $priority = 1) - { - /** @psalm-var TPriority $priority */ - $priority = (int) $priority; - $this->items[] = [ - 'data' => $data, - 'priority' => $priority, - ]; - $this->getQueue()->insert($data, $priority); - return $this; - } - - /** - * Remove an item from the queue - * - * This is different than {@link extract()}; its purpose is to dequeue an - * item. - * - * This operation is potentially expensive, as it requires - * re-initialization and re-population of the inner queue. - * - * Note: this removes the first item matching the provided item found. If - * the same item has been added multiple times, it will not remove other - * instances. - * - * @return bool False if the item was not found, true otherwise. - */ - public function remove(mixed $datum) - { - $found = false; - $key = null; - foreach ($this->items as $key => $item) { - if ($item['data'] === $datum) { - $found = true; - break; - } - } - if ($found && $key !== null) { - unset($this->items[$key]); - $this->queue = null; - - if (! $this->isEmpty()) { - $queue = $this->getQueue(); - foreach ($this->items as $item) { - $queue->insert($item['data'], $item['priority']); - } - } - return true; - } - return false; - } - - /** - * Is the queue empty? - * - * @return bool - */ - public function isEmpty() - { - return 0 === $this->count(); - } - - /** - * How many items are in the queue? - * - * @return int - */ - #[ReturnTypeWillChange] - public function count() - { - return count($this->items); - } - - /** - * Peek at the top node in the queue, based on priority. - * - * @return TValue - */ - public function top() - { - $queue = clone $this->getQueue(); - - return $queue->top(); - } - - /** - * Extract a node from the inner queue and sift up - * - * @return TValue - */ - public function extract() - { - $value = $this->getQueue()->extract(); - - $keyToRemove = null; - $highestPriority = null; - foreach ($this->items as $key => $item) { - if ($item['data'] !== $value) { - continue; - } - - if (null === $highestPriority) { - $highestPriority = $item['priority']; - $keyToRemove = $key; - continue; - } - - if ($highestPriority >= $item['priority']) { - continue; - } - - $highestPriority = $item['priority']; - $keyToRemove = $key; - } - - if ($keyToRemove !== null) { - unset($this->items[$keyToRemove]); - } - - return $value; - } - - /** - * Retrieve the inner iterator - * - * SplPriorityQueue acts as a heap, which typically implies that as items - * are iterated, they are also removed. This does not work for situations - * where the queue may be iterated multiple times. As such, this class - * aggregates the values, and also injects an SplPriorityQueue. This method - * retrieves the inner queue object, and clones it for purposes of - * iteration. - * - * @return \SplPriorityQueue - */ - #[ReturnTypeWillChange] - public function getIterator() - { - $queue = $this->getQueue(); - return clone $queue; - } - - /** - * Serialize the data structure - * - * @return string - */ - public function serialize() - { - return serialize($this->__serialize()); - } - - /** - * Magic method used for serializing of an instance. - * - * @return list - */ - public function __serialize() - { - return $this->items; - } - - /** - * Unserialize a string into a PriorityQueue object - * - * Serialization format is compatible with {@link SplPriorityQueue} - * - * @param string $data - * @return void - */ - public function unserialize($data) - { - $toUnserialize = unserialize($data); - if (! is_array($toUnserialize)) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance; corrupt serialization data', - self::class - )); - } - - /** @psalm-var list $toUnserialize */ - - $this->__unserialize($toUnserialize); - } - - /** - * Magic method used to rebuild an instance. - * - * @param list $data Data array. - * @return void - */ - public function __unserialize($data) - { - foreach ($data as $item) { - $this->insert($item['data'], $item['priority']); - } - } - - /** - * Serialize to an array - * By default, returns only the item data, and in the order registered (not - * sorted). You may provide one of the EXTR_* flags as an argument, allowing - * the ability to return priorities or both data and priority. - * - * @param int $flag - * @return array - * @psalm-return ($flag is self::EXTR_BOTH - * ? list - * : $flag is self::EXTR_PRIORITY - * ? list - * : list - * ) - */ - public function toArray($flag = self::EXTR_DATA) - { - return match ($flag) { - self::EXTR_BOTH => $this->items, - self::EXTR_PRIORITY => array_map(static fn($item): int => $item['priority'], $this->items), - default => array_map(static fn($item): mixed => $item['data'], $this->items), - }; - } - - /** - * Specify the internal queue class - * - * Please see {@link getIterator()} for details on the necessity of an - * internal queue class. The class provided should extend SplPriorityQueue. - * - * @param class-string<\SplPriorityQueue> $class - * @return $this - */ - public function setInternalQueueClass($class) - { - /** @psalm-suppress RedundantCastGivenDocblockType */ - $this->queueClass = (string) $class; - return $this; - } - - /** - * Does the queue contain the given datum? - * - * @param TValue $datum - * @return bool - */ - public function contains($datum) - { - foreach ($this->items as $item) { - if ($item['data'] === $datum) { - return true; - } - } - return false; - } - - /** - * Does the queue have an item with the given priority? - * - * @param TPriority $priority - * @return bool - */ - public function hasPriority($priority) - { - foreach ($this->items as $item) { - if ($item['priority'] === $priority) { - return true; - } - } - return false; - } - - /** - * Get the inner priority queue instance - * - * @throws Exception\DomainException - * @return \SplPriorityQueue - * @psalm-assert !null $this->queue - */ - protected function getQueue() - { - if (null === $this->queue) { - /** @psalm-suppress UnsafeInstantiation */ - $queue = new $this->queueClass(); - /** @psalm-var \SplPriorityQueue $queue */ - $this->queue = $queue; - /** @psalm-suppress DocblockTypeContradiction */ - if (! $this->queue instanceof \SplPriorityQueue) { - throw new Exception\DomainException(sprintf( - 'PriorityQueue expects an internal queue of type SplPriorityQueue; received "%s"', - $queue::class - )); - } - } - - return $this->queue; - } - - /** - * Add support for deep cloning - * - * @return void - */ - public function __clone() - { - if (null !== $this->queue) { - $this->queue = clone $this->queue; - } - } -} diff --git a/lib/laminas/laminas-stdlib/src/Request.php b/lib/laminas/laminas-stdlib/src/Request.php deleted file mode 100644 index 65026f609..000000000 --- a/lib/laminas/laminas-stdlib/src/Request.php +++ /dev/null @@ -1,10 +0,0 @@ - - */ -class SplPriorityQueue extends \SplPriorityQueue implements Serializable -{ - /** @var int Seed used to ensure queue order for items of the same priority */ - protected $serial = PHP_INT_MAX; - - /** - * Insert a value with a given priority - * - * Utilizes {@var $serial} to ensure that values of equal priority are - * emitted in the same order in which they are inserted. - * - * @param TValue $value - * @param TPriority $priority - * @return void - */ - #[ReturnTypeWillChange] // Inherited return type should be bool - public function insert($value, $priority) - { - if (! is_array($priority)) { - $priority = [$priority, $this->serial--]; - } - - parent::insert($value, $priority); - } - - /** - * Serialize to an array - * - * Array will be priority => data pairs - * - * @return list - */ - public function toArray() - { - $array = []; - foreach (clone $this as $item) { - $array[] = $item; - } - return $array; - } - - /** - * Serialize - * - * @return string - */ - public function serialize() - { - return serialize($this->__serialize()); - } - - /** - * Magic method used for serializing of an instance. - * - * @return array - */ - public function __serialize() - { - $clone = clone $this; - $clone->setExtractFlags(self::EXTR_BOTH); - - $data = []; - foreach ($clone as $item) { - $data[] = $item; - } - return $data; - } - - /** - * Deserialize - * - * @param string $data - * @return void - */ - public function unserialize($data) - { - $toUnserialize = unserialize($data); - if (! is_array($toUnserialize)) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance; corrupt serialization data', - self::class - )); - } - - $this->__unserialize($toUnserialize); - } - - /** - * Magic method used to rebuild an instance. - * - * @param array $data Data array. - * @return void - */ - public function __unserialize($data) - { - $this->serial = PHP_INT_MAX; - - foreach ($data as $item) { - if (! is_array($item)) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance: corrupt item; expected array, received %s', - self::class, - get_debug_type($item) - )); - } - - if (! array_key_exists('data', $item)) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance: corrupt item; missing "data" element', - self::class - )); - } - - $priority = 1; - if (array_key_exists('priority', $item)) { - $priority = (int) $item['priority']; - } - - $this->insert($item['data'], $priority); - } - } -} diff --git a/lib/laminas/laminas-stdlib/src/SplQueue.php b/lib/laminas/laminas-stdlib/src/SplQueue.php deleted file mode 100644 index 2656a856b..000000000 --- a/lib/laminas/laminas-stdlib/src/SplQueue.php +++ /dev/null @@ -1,94 +0,0 @@ - - */ -class SplQueue extends \SplQueue implements Serializable -{ - /** - * Return an array representing the queue - * - * @return list - */ - public function toArray() - { - $array = []; - foreach ($this as $item) { - $array[] = $item; - } - return $array; - } - - /** - * Serialize - * - * @return string - */ - #[ReturnTypeWillChange] - public function serialize() - { - return serialize($this->__serialize()); - } - - /** - * Magic method used for serializing of an instance. - * - * @return list - */ - #[ReturnTypeWillChange] - public function __serialize() - { - return $this->toArray(); - } - - /** - * Unserialize - * - * @param string $data - * @return void - */ - #[ReturnTypeWillChange] - public function unserialize($data) - { - $toUnserialize = unserialize($data); - if (! is_array($toUnserialize)) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance; corrupt serialization data', - self::class - )); - } - - $this->__unserialize($toUnserialize); - } - - /** - * Magic method used to rebuild an instance. - * - * @param array $data Data array. - * @return void - */ - #[ReturnTypeWillChange] - public function __unserialize($data) - { - foreach ($data as $item) { - $this->push($item); - } - } -} diff --git a/lib/laminas/laminas-stdlib/src/SplStack.php b/lib/laminas/laminas-stdlib/src/SplStack.php deleted file mode 100644 index 52564fde8..000000000 --- a/lib/laminas/laminas-stdlib/src/SplStack.php +++ /dev/null @@ -1,93 +0,0 @@ - - */ -class SplStack extends \SplStack implements Serializable -{ - /** - * Serialize to an array representing the stack - * - * @return list - */ - public function toArray() - { - $array = []; - foreach ($this as $item) { - $array[] = $item; - } - return $array; - } - - /** - * Serialize - * - * @return string - */ - #[ReturnTypeWillChange] - public function serialize() - { - return serialize($this->__serialize()); - } - - /** - * Magic method used for serializing of an instance. - * - * @return list - */ - #[ReturnTypeWillChange] - public function __serialize() - { - return $this->toArray(); - } - - /** - * Unserialize - * - * @param string $data - * @return void - */ - #[ReturnTypeWillChange] - public function unserialize($data) - { - $toUnserialize = unserialize($data); - if (! is_array($toUnserialize)) { - throw new UnexpectedValueException(sprintf( - 'Cannot deserialize %s instance; corrupt serialization data', - self::class - )); - } - - $this->__unserialize($toUnserialize); - } - - /** - * Magic method used to rebuild an instance. - * - * @param array $data Data array. - * @return void - */ - #[ReturnTypeWillChange] - public function __unserialize($data) - { - foreach ($data as $item) { - $this->unshift($item); - } - } -} diff --git a/lib/laminas/laminas-stdlib/src/StringUtils.php b/lib/laminas/laminas-stdlib/src/StringUtils.php deleted file mode 100644 index ffc3ad553..000000000 --- a/lib/laminas/laminas-stdlib/src/StringUtils.php +++ /dev/null @@ -1,213 +0,0 @@ ->|null - */ - protected static $wrapperRegistry; - - /** - * A list of known single-byte character encodings (upper-case) - * - * @var string[] - */ - protected static $singleByteEncodings = [ - 'ASCII', - '7BIT', - '8BIT', - 'ISO-8859-1', - 'ISO-8859-2', - 'ISO-8859-3', - 'ISO-8859-4', - 'ISO-8859-5', - 'ISO-8859-6', - 'ISO-8859-7', - 'ISO-8859-8', - 'ISO-8859-9', - 'ISO-8859-10', - 'ISO-8859-11', - 'ISO-8859-13', - 'ISO-8859-14', - 'ISO-8859-15', - 'ISO-8859-16', - 'CP-1251', - 'CP-1252', - // TODO - ]; - - /** - * Is PCRE compiled with Unicode support? - * - * @var bool - **/ - protected static $hasPcreUnicodeSupport; - - /** - * Get registered wrapper classes - * - * @return string[] - * @psalm-return list> - */ - public static function getRegisteredWrappers() - { - if (static::$wrapperRegistry === null) { - static::$wrapperRegistry = []; - - if (extension_loaded('intl')) { - static::$wrapperRegistry[] = Intl::class; - } - - if (extension_loaded('mbstring')) { - static::$wrapperRegistry[] = MbString::class; - } - - if (extension_loaded('iconv')) { - static::$wrapperRegistry[] = Iconv::class; - } - - static::$wrapperRegistry[] = Native::class; - } - - return static::$wrapperRegistry; - } - - /** - * Register a string wrapper class - * - * @param class-string $wrapper - * @return void - */ - public static function registerWrapper($wrapper) - { - $wrapper = (string) $wrapper; - // using getRegisteredWrappers() here to ensure that the list is initialized - if (! in_array($wrapper, static::getRegisteredWrappers(), true)) { - static::$wrapperRegistry[] = $wrapper; - } - } - - /** - * Unregister a string wrapper class - * - * @param class-string $wrapper - * @return void - */ - public static function unregisterWrapper($wrapper) - { - // using getRegisteredWrappers() here to ensure that the list is initialized - $index = array_search((string) $wrapper, static::getRegisteredWrappers(), true); - if ($index !== false) { - unset(static::$wrapperRegistry[$index]); - } - } - - /** - * Reset all registered wrappers so the default wrappers will be used - * - * @return void - */ - public static function resetRegisteredWrappers() - { - static::$wrapperRegistry = null; - } - - /** - * Get the first string wrapper supporting the given character encoding - * and supports to convert into the given convert encoding. - * - * @param string $encoding Character encoding to support - * @param string|null $convertEncoding OPTIONAL character encoding to convert in - * @return StringWrapperInterface - * @throws Exception\RuntimeException If no wrapper supports given character encodings. - */ - public static function getWrapper($encoding = 'UTF-8', $convertEncoding = null) - { - foreach (static::getRegisteredWrappers() as $wrapperClass) { - if ($wrapperClass::isSupported($encoding, $convertEncoding)) { - $wrapper = new $wrapperClass($encoding, $convertEncoding); - $wrapper->setEncoding($encoding, $convertEncoding); - return $wrapper; - } - } - - throw new Exception\RuntimeException( - 'No wrapper found supporting "' . $encoding . '"' - . ($convertEncoding !== null ? ' and "' . $convertEncoding . '"' : '') - ); - } - - /** - * Get a list of all known single-byte character encodings - * - * @return string[] - */ - public static function getSingleByteEncodings() - { - return static::$singleByteEncodings; - } - - /** - * Check if a given encoding is a known single-byte character encoding - * - * @param string $encoding - * @return bool - */ - public static function isSingleByteEncoding($encoding) - { - return in_array(strtoupper($encoding), static::$singleByteEncodings); - } - - /** - * Check if a given string is valid UTF-8 encoded - * - * @param string $str - * @return bool - */ - public static function isValidUtf8($str) - { - return is_string($str) && ($str === '' || preg_match('/^./su', $str) === 1); - } - - /** - * Is PCRE compiled with Unicode support? - * - * @return bool - */ - public static function hasPcreUnicodeSupport() - { - if (static::$hasPcreUnicodeSupport === null) { - ErrorHandler::start(); - static::$hasPcreUnicodeSupport = defined('PREG_BAD_UTF8_OFFSET_ERROR') && preg_match('/\pL/u', 'a') === 1; - ErrorHandler::stop(); - } - return static::$hasPcreUnicodeSupport; - } -} diff --git a/lib/laminas/laminas-stdlib/src/StringWrapper/AbstractStringWrapper.php b/lib/laminas/laminas-stdlib/src/StringWrapper/AbstractStringWrapper.php deleted file mode 100644 index a96c7a468..000000000 --- a/lib/laminas/laminas-stdlib/src/StringWrapper/AbstractStringWrapper.php +++ /dev/null @@ -1,278 +0,0 @@ -convertEncoding = $convertEncodingUpper; - } else { - $this->convertEncoding = null; - } - $this->encoding = $encodingUpper; - - return $this; - } - - /** - * Get the defined character encoding to work with - * - * @return null|string - * @throws Exception\LogicException If no encoding was defined. - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Get the defined character encoding to convert to - * - * @return string|null - */ - public function getConvertEncoding() - { - return $this->convertEncoding; - } - - /** - * Convert a string from defined character encoding to the defined convert encoding - * - * @param string $str - * @param bool $reverse - * @return string|false - */ - public function convert($str, $reverse = false) - { - $encoding = $this->getEncoding(); - $convertEncoding = $this->getConvertEncoding(); - if ($convertEncoding === null) { - throw new Exception\LogicException( - 'No convert encoding defined' - ); - } - - if ($encoding === $convertEncoding) { - return $str; - } - - $from = $reverse ? $convertEncoding : $encoding; - $to = $reverse ? $encoding : $convertEncoding; - throw new Exception\RuntimeException(sprintf( - 'Converting from "%s" to "%s" isn\'t supported by this string wrapper', - $from ?? '', - $to ?? '' - )); - } - - /** - * Wraps a string to a given number of characters - * - * @param string $string - * @param int $width - * @param string $break - * @param bool $cut - * @return string|false - */ - public function wordWrap($string, $width = 75, $break = "\n", $cut = false) - { - $string = (string) $string; - if ($string === '') { - return ''; - } - - $break = (string) $break; - if ($break === '') { - throw new Exception\InvalidArgumentException('Break string cannot be empty'); - } - - $width = (int) $width; - if ($width === 0 && $cut) { - throw new Exception\InvalidArgumentException('Cannot force cut when width is zero'); - } - - if (null === $this->getEncoding() || StringUtils::isSingleByteEncoding($this->getEncoding())) { - return wordwrap($string, $width, $break, $cut); - } - - $stringWidth = $this->strlen($string); - $breakWidth = $this->strlen($break); - - $result = ''; - $lastStart = $lastSpace = 0; - - for ($current = 0; $current < $stringWidth; $current++) { - $char = $this->substr($string, $current, 1); - - $possibleBreak = $char; - if ($breakWidth !== 1) { - $possibleBreak = $this->substr($string, $current, $breakWidth); - } - - if ($possibleBreak === $break) { - $result .= $this->substr($string, $lastStart, $current - $lastStart + $breakWidth); - $current += $breakWidth - 1; - $lastStart = $lastSpace = $current + 1; - continue; - } - - if ($char === ' ') { - if ($current - $lastStart >= $width) { - $result .= $this->substr($string, $lastStart, $current - $lastStart) . $break; - $lastStart = $current + 1; - } - - $lastSpace = $current; - continue; - } - - if ($current - $lastStart >= $width && $cut && $lastStart >= $lastSpace) { - $result .= $this->substr($string, $lastStart, $current - $lastStart) . $break; - $lastStart = $lastSpace = $current; - continue; - } - - if ($current - $lastStart >= $width && $lastStart < $lastSpace) { - $result .= $this->substr($string, $lastStart, $lastSpace - $lastStart) . $break; - $lastStart = $lastSpace += 1; - continue; - } - } - - if ($lastStart !== $current) { - $result .= $this->substr($string, $lastStart, $current - $lastStart); - } - - return $result; - } - - /** - * Pad a string to a certain length with another string - * - * @param string $input - * @param int $padLength - * @param string $padString - * @param int $padType - * @return string - */ - public function strPad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT) - { - if (null === $this->getEncoding() || StringUtils::isSingleByteEncoding($this->getEncoding())) { - return str_pad($input, $padLength, $padString, $padType); - } - - $lengthOfPadding = $padLength - $this->strlen($input); - if ($lengthOfPadding <= 0) { - return $input; - } - - $padStringLength = $this->strlen($padString); - if ($padStringLength === 0) { - return $input; - } - - $repeatCount = (int) floor($lengthOfPadding / $padStringLength); - - if ($padType === STR_PAD_BOTH) { - $repeatCountLeft = $repeatCountRight = ($repeatCount - $repeatCount % 2) / 2; - - $lastStringLength = $lengthOfPadding - 2 * $repeatCountLeft * $padStringLength; - $lastStringLeftLength = $lastStringRightLength = (int) floor($lastStringLength / 2); - $lastStringRightLength += $lastStringLength % 2; - - $lastStringLeft = $this->substr($padString, 0, $lastStringLeftLength); - $lastStringRight = $this->substr($padString, 0, $lastStringRightLength); - - return str_repeat($padString, $repeatCountLeft) . $lastStringLeft - . $input - . str_repeat($padString, $repeatCountRight) . $lastStringRight; - } - - $lastString = $this->substr($padString, 0, $lengthOfPadding % $padStringLength); - - if ($padType === STR_PAD_LEFT) { - return str_repeat($padString, $repeatCount) . $lastString . $input; - } - - return $input . str_repeat($padString, $repeatCount) . $lastString; - } -} diff --git a/lib/laminas/laminas-stdlib/src/StringWrapper/Iconv.php b/lib/laminas/laminas-stdlib/src/StringWrapper/Iconv.php deleted file mode 100644 index 2f52b74e1..000000000 --- a/lib/laminas/laminas-stdlib/src/StringWrapper/Iconv.php +++ /dev/null @@ -1,302 +0,0 @@ -getEncoding()); - } - - /** - * Returns the portion of string specified by the start and length parameters - * - * @param string $str - * @param int $offset - * @param int|null $length - * @return string|false - */ - public function substr($str, $offset = 0, $length = null) - { - $length ??= $this->strlen($str); - assert($length !== false); - - return iconv_substr($str, $offset, $length, $this->getEncoding()); - } - - /** - * Find the position of the first occurrence of a substring in a string - * - * @param string $haystack - * @param string $needle - * @param int $offset - * @return int|false - */ - public function strpos($haystack, $needle, $offset = 0) - { - $encoding = $this->getEncoding(); - assert($encoding !== null); - - return iconv_strpos($haystack, $needle, $offset, $encoding); - } - - /** - * Convert a string from defined encoding to the defined convert encoding - * - * @param string $str - * @param bool $reverse - * @return string|false - */ - public function convert($str, $reverse = false) - { - $encoding = $this->getEncoding(); - $convertEncoding = $this->getConvertEncoding(); - if ($convertEncoding === null) { - throw new Exception\LogicException( - 'No convert encoding defined' - ); - } - - if ($encoding === $convertEncoding) { - return $str; - } - - $fromEncoding = $reverse ? $convertEncoding : $encoding; - $toEncoding = $reverse ? $encoding : $convertEncoding; - - if (null === $toEncoding || null === $fromEncoding) { - return $str; - } - - // automatically add "//IGNORE" to not stop converting on invalid characters - // invalid characters triggers a notice anyway - return iconv($fromEncoding, $toEncoding . '//IGNORE', $str); - } -} diff --git a/lib/laminas/laminas-stdlib/src/StringWrapper/Intl.php b/lib/laminas/laminas-stdlib/src/StringWrapper/Intl.php deleted file mode 100644 index 81a6b9a8a..000000000 --- a/lib/laminas/laminas-stdlib/src/StringWrapper/Intl.php +++ /dev/null @@ -1,89 +0,0 @@ -getEncoding()); - } - - /** - * Returns the portion of string specified by the start and length parameters - * - * @param string $str - * @param int $offset - * @param int|null $length - * @return string|false - */ - public function substr($str, $offset = 0, $length = null) - { - return mb_substr($str, $offset, $length, $this->getEncoding()); - } - - /** - * Find the position of the first occurrence of a substring in a string - * - * @param string $haystack - * @param string $needle - * @param int $offset - * @return int|false - */ - public function strpos($haystack, $needle, $offset = 0) - { - return mb_strpos($haystack, $needle, $offset, $this->getEncoding()); - } - - /** - * Convert a string from defined encoding to the defined convert encoding - * - * @param string $str - * @param bool $reverse - * @return string|false - */ - public function convert($str, $reverse = false) - { - $encoding = $this->getEncoding(); - $convertEncoding = $this->getConvertEncoding(); - - if ($convertEncoding === null) { - throw new Exception\LogicException( - 'No convert encoding defined' - ); - } - - if ($encoding === $convertEncoding) { - return $str; - } - - $fromEncoding = $reverse ? $convertEncoding : $encoding; - $toEncoding = $reverse ? $encoding : $convertEncoding; - - return mb_convert_encoding($str, $toEncoding ?? '', $fromEncoding ?? ''); - } -} diff --git a/lib/laminas/laminas-stdlib/src/StringWrapper/Native.php b/lib/laminas/laminas-stdlib/src/StringWrapper/Native.php deleted file mode 100644 index a137d4ae1..000000000 --- a/lib/laminas/laminas-stdlib/src/StringWrapper/Native.php +++ /dev/null @@ -1,135 +0,0 @@ -convertEncoding = $encodingUpper; - } - - if ($convertEncoding !== null) { - if ($encodingUpper !== strtoupper($convertEncoding)) { - throw new Exception\InvalidArgumentException( - 'Wrapper doesn\'t support to convert between character encodings' - ); - } - - $this->convertEncoding = $encodingUpper; - } else { - $this->convertEncoding = null; - } - $this->encoding = $encodingUpper; - - return $this; - } - - /** - * Returns the length of the given string - * - * @param string $str - * @return int|false - */ - public function strlen($str) - { - return strlen($str); - } - - /** - * Returns the portion of string specified by the start and length parameters - * - * @param string $str - * @param int $offset - * @param int|null $length - * @return string|false - */ - public function substr($str, $offset = 0, $length = null) - { - return substr($str, $offset, $length); - } - - /** - * Find the position of the first occurrence of a substring in a string - * - * @param string $haystack - * @param string $needle - * @param int $offset - * @return int|false - */ - public function strpos($haystack, $needle, $offset = 0) - { - return strpos($haystack, $needle, $offset); - } -} diff --git a/lib/laminas/laminas-stdlib/src/StringWrapper/StringWrapperInterface.php b/lib/laminas/laminas-stdlib/src/StringWrapper/StringWrapperInterface.php deleted file mode 100644 index 700799f91..000000000 --- a/lib/laminas/laminas-stdlib/src/StringWrapper/StringWrapperInterface.php +++ /dev/null @@ -1,108 +0,0 @@ - ## 🇷🇺 Русским гражданам -> -> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм. -> -> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую. -> -> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!" -> -> ## 🇺🇸 To Citizens of Russia -> -> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism. -> -> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences. -> -> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!" - -laminas-validator provides a set of commonly needed validators. It also provides a -simple validator chaining mechanism by which multiple validators may be applied -to a single datum in a user-defined order. - -## Installation - -Run the following to install this library: - -```bash -$ composer require laminas/laminas-validator -``` - -## Documentation - -Browse the documentation online at https://docs.laminas.dev/laminas-validator/ - -## Support - -* [Issues](https://github.com/laminas/laminas-validator/issues/) -* [Chat](https://laminas.dev/chat/) -* [Forum](https://discourse.laminas.dev/) diff --git a/lib/laminas/laminas-validator/bin/update_hostname_validator.php b/lib/laminas/laminas-validator/bin/update_hostname_validator.php deleted file mode 100644 index fbc461634..000000000 --- a/lib/laminas/laminas-validator/bin/update_hostname_validator.php +++ /dev/null @@ -1,196 +0,0 @@ - $newFileContent */ -$newFileContent = []; // new file content -$insertDone = false; // becomes 'true' when we find start of $validTlds declaration -$insertFinish = false; // becomes 'true' when we find end of $validTlds declaration -$checkOnly = isset($argv[1]) ? $argv[1] === '--check-only' : false; -$response = getOfficialTLDs(); -$ianaVersion = getVersionFromString('Version', strtok($response->getBody(), "\n")); -$validatorVersion = getVersionFromString('IanaVersion', file_get_contents(LAMINAS_HOSTNAME_VALIDATOR_FILE)); - -if ($checkOnly && $ianaVersion > $validatorVersion) { - printf( - 'TLDs must be updated, please run `php bin/update_hostname_validator.php` and push your changes%s', - PHP_EOL - ); - exit(1); -} - -if ($checkOnly) { - printf('TLDs are up-to-date%s', PHP_EOL); - exit(0); -} - -foreach (file(LAMINAS_HOSTNAME_VALIDATOR_FILE) as $line) { - // Replace old version number with new one - if (preg_match('/\*\s+IanaVersion\s+\d+/', $line, $matches)) { - $newFileContent[] = sprintf(" * IanaVersion %s\n", $ianaVersion); - continue; - } - - if ($insertDone === $insertFinish) { - // Outside of $validTlds definition; keep line as-is - $newFileContent[] = $line; - } - - if ($insertFinish) { - continue; - } - - if ($insertDone) { - // Detect where the $validTlds declaration ends - if (preg_match('/^\s+\];\s*$/', $line)) { - $newFileContent[] = $line; - $insertFinish = true; - } - - continue; - } - - // Detect where the $validTlds declaration begins - if (preg_match('/^\s+protected\s+\$validTlds\s+=\s+\[\s*$/', $line)) { - $newFileContent = array_merge($newFileContent, getNewValidTlds($response->getBody())); - $insertDone = true; - } -} - -if (! $insertDone) { - printf('Error: cannot find line with "protected $validTlds"%s', PHP_EOL); - exit(1); -} - -if (!$insertFinish) { - printf('Error: cannot find end of $validTlds declaration%s', PHP_EOL); - exit(1); -} - -if (false === @file_put_contents(LAMINAS_HOSTNAME_VALIDATOR_FILE, $newFileContent)) { - printf('Error: cannot write info file "%s"%s', LAMINAS_HOSTNAME_VALIDATOR_FILE, PHP_EOL); - exit(1); -} - -printf('Validator TLD file updated.%s', PHP_EOL); -exit(0); - -/** - * Get Official TLDs - * - * @return \Laminas\Http\Response - * @throws Exception - */ -function getOfficialTLDs() -{ - $client = new Client(); - $client->setOptions([ - 'adapter' => 'Laminas\Http\Client\Adapter\Curl', - ]); - $client->setUri(IANA_URL); - $client->setMethod('GET'); - - $response = $client->send(); - if (! $response->isSuccess()) { - throw new \Exception(sprintf("Error: cannot get '%s'%s", IANA_URL, PHP_EOL)); - } - return $response; -} - -/** - * Extract the first match of a string like - * "Version 2015072300" from the given string - * - * @param string $prefix - * @param string $string - * @return string - * @throws Exception - */ -function getVersionFromString($prefix, $string) -{ - $matches = []; - if (! preg_match(sprintf('/%s\s+((\d+)?)/', $prefix), $string, $matches)) { - throw new Exception('Error: cannot get last update date'); - } - - return $matches[1]; -} - -/** - * Extract new Valid TLDs from a string containing one per line. - * - * @param string $string - * @return list - */ -function getNewValidTlds($string) -{ - $decodePunycode = getPunycodeDecoder(); - - // Get new TLDs from the list previously fetched - $newValidTlds = []; - foreach (preg_grep('/^[^#]/', preg_split("#\r?\n#", $string)) as $line) { - $newValidTlds []= sprintf( - "%s'%s',\n", - str_repeat(' ', 8), - $decodePunycode(strtolower($line)) - ); - } - - return $newValidTlds; -} - -/** - * Retrieve and return a punycode decoder. - * - * TLDs are puny encoded. - * - * We need a decodePunycode function to translate TLDs to UTF-8: - * - * - use idn_to_utf8 if available - * - otherwise, use Hostname::decodePunycode() - * - * @return callable - */ -function getPunycodeDecoder() -{ - if (function_exists('idn_to_utf8')) { - return function ($domain) { - return idn_to_utf8($domain, 0, INTL_IDNA_VARIANT_UTS46); - }; - } - - $hostnameValidator = new Hostname(); - $reflection = new ReflectionClass(get_class($hostnameValidator)); - $decodePunyCode = $reflection->getMethod('decodePunycode'); - $decodePunyCode->setAccessible(true); - - return function ($encode) use ($hostnameValidator, $decodePunyCode) { - if (strpos($encode, 'xn--') === 0) { - return $decodePunyCode->invokeArgs($hostnameValidator, [substr($encode, 4)]); - } - return $encode; - }; -} diff --git a/lib/laminas/laminas-validator/composer.json b/lib/laminas/laminas-validator/composer.json deleted file mode 100644 index 52aab145b..000000000 --- a/lib/laminas/laminas-validator/composer.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "name": "laminas/laminas-validator", - "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", - "license": "BSD-3-Clause", - "keywords": [ - "laminas", - "validator" - ], - "homepage": "https://laminas.dev", - "support": { - "docs": "https://docs.laminas.dev/laminas-validator/", - "issues": "https://github.com/laminas/laminas-validator/issues", - "source": "https://github.com/laminas/laminas-validator", - "rss": "https://github.com/laminas/laminas-validator/releases.atom", - "chat": "https://laminas.dev/chat", - "forum": "https://discourse.laminas.dev" - }, - "config": { - "sort-packages": true, - "platform": { - "php": "8.0.99" - }, - "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true - } - }, - "extra": { - "laminas": { - "component": "Laminas\\Validator", - "config-provider": "Laminas\\Validator\\ConfigProvider" - } - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "laminas/laminas-servicemanager": "^3.12.0", - "laminas/laminas-stdlib": "^3.13" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "laminas/laminas-db": "^2.15.0", - "laminas/laminas-filter": "^2.23.0", - "laminas/laminas-http": "^2.17.0", - "laminas/laminas-i18n": "^2.19", - "laminas/laminas-session": "^2.13.0", - "laminas/laminas-uri": "^2.10.0", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.18.0", - "psr/http-client": "^1.0.1", - "psr/http-factory": "^1.0.1", - "psr/http-message": "^1.0.1", - "vimeo/psalm": "^4.28" - }, - "suggest": { - "laminas/laminas-db": "Laminas\\Db component, required by the (No)RecordExists validator", - "laminas/laminas-filter": "Laminas\\Filter component, required by the Digits validator", - "laminas/laminas-i18n": "Laminas\\I18n component to allow translation of validation error messages", - "laminas/laminas-i18n-resources": "Translations of validator messages", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", - "laminas/laminas-session": "Laminas\\Session component, ^2.8; required by the Csrf validator", - "laminas/laminas-uri": "Laminas\\Uri component, required by the Uri and Sitemap\\Loc validators", - "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators" - }, - "autoload": { - "psr-4": { - "Laminas\\Validator\\": "src/" - } - }, - "autoload-dev": { - "files": [ - "test/autoload.php" - ], - "psr-4": { - "LaminasTest\\Validator\\": "test/" - } - }, - "scripts": { - "check": [ - "@cs-check", - "@test" - ], - "cs-check": "phpcs", - "cs-fix": "phpcbf", - "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "static-analysis": "psalm --shepherd --stats" - }, - "conflict": { - "zendframework/zend-validator": "*" - } -} diff --git a/lib/laminas/laminas-validator/composer.lock b/lib/laminas/laminas-validator/composer.lock deleted file mode 100644 index 395931f5e..000000000 --- a/lib/laminas/laminas-validator/composer.lock +++ /dev/null @@ -1,5020 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "6e7995bf6995ad1fed5a115c0fcfc0b6", - "packages": [ - { - "name": "laminas/laminas-servicemanager", - "version": "3.19.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "ed160729bb8721127efdaac799f9a298963345b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/ed160729bb8721127efdaac799f9a298963345b1", - "reference": "ed160729bb8721127efdaac799f9a298963345b1", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.2.1", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", - "psr/container": "^1.0" - }, - "conflict": { - "ext-psr": "*", - "laminas/laminas-code": "<3.3.1", - "zendframework/zend-code": "<3.3.1", - "zendframework/zend-servicemanager": "*" - }, - "provide": { - "psr/container-implementation": "^1.0" - }, - "replace": { - "container-interop/container-interop": "^1.2.0" - }, - "require-dev": { - "composer/package-versions-deprecated": "^1.11.99.5", - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-container-config-test": "^0.7", - "laminas/laminas-dependency-plugin": "^2.2", - "mikey179/vfsstream": "^1.6.11@alpha", - "ocramius/proxy-manager": "^2.14.1", - "phpbench/phpbench": "^1.2.6", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.28" - }, - "suggest": { - "ocramius/proxy-manager": "ProxyManager ^2.1.1 to handle lazy initialization of services" - }, - "bin": [ - "bin/generate-deps-for-config-factory", - "bin/generate-factory-for-class" - ], - "type": "library", - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Laminas\\ServiceManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Factory-Driven Dependency Injection Container", - "homepage": "https://laminas.dev", - "keywords": [ - "PSR-11", - "dependency-injection", - "di", - "dic", - "laminas", - "service-manager", - "servicemanager" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-servicemanager/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-servicemanager/issues", - "rss": "https://github.com/laminas/laminas-servicemanager/releases.atom", - "source": "https://github.com/laminas/laminas-servicemanager" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-10T20:59:22+00:00" - }, - { - "name": "laminas/laminas-stdlib", - "version": "3.15.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "63b66bd4b696f024f42616b9d95cdb10e5109c27" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/63b66bd4b696f024f42616b9d95cdb10e5109c27", - "reference": "63b66bd4b696f024f42616b9d95cdb10e5109c27", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-stdlib": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.4.0", - "phpbench/phpbench": "^1.2.6", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.28" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Stdlib\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "SPL extensions, array utilities, error handlers, and more", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "stdlib" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-stdlib/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-stdlib/issues", - "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", - "source": "https://github.com/laminas/laminas-stdlib" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-10T19:10:24+00:00" - }, - { - "name": "psr/container", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "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/1.1.2" - }, - "time": "2021-11-05T16:50:12+00:00" - } - ], - "packages-dev": [ - { - "name": "amphp/amp", - "version": "v2.6.2", - "source": { - "type": "git", - "url": "https://github.com/amphp/amp.git", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", - "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^7 | ^8 | ^9", - "psalm/phar": "^3.11@dev", - "react/promise": "^2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php", - "lib/Internal/functions.php" - ], - "psr-4": { - "Amp\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "https://amphp.org/amp", - "keywords": [ - "async", - "asynchronous", - "awaitable", - "concurrency", - "event", - "event-loop", - "future", - "non-blocking", - "promise" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.2" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2022-02-20T17:52:18+00:00" - }, - { - "name": "amphp/byte-stream", - "version": "v1.8.1", - "source": { - "type": "git", - "url": "https://github.com/amphp/byte-stream.git", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", - "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", - "shasum": "" - }, - "require": { - "amphp/amp": "^2", - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.4", - "friendsofphp/php-cs-fixer": "^2.3", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^6 || ^7 || ^8", - "psalm/phar": "^3.11.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php" - ], - "psr-4": { - "Amp\\ByteStream\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "http://amphp.org/byte-stream", - "keywords": [ - "amp", - "amphp", - "async", - "io", - "non-blocking", - "stream" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2021-03-30T17:13:30+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-01-17T14:14:24+00:00" - }, - { - "name": "composer/pcre", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb", - "reference": "4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], - "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.0.2" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-11-03T20:24:16+00:00" - }, - { - "name": "composer/semver", - "version": "3.3.2", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-04-01T19:23:25+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", - "shasum": "" - }, - "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" - }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-02-25T21:32:43+00:00" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2022-02-04T12:51:07+00:00" - }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "v0.1.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "implementation of xdg base directory specification for php", - "support": { - "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", - "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" - }, - "time": "2019-12-04T15:06:13+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "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" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "felixfbecker/advanced-json-rpc", - "version": "v3.2.1", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "shasum": "" - }, - "require": { - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "php": "^7.1 || ^8.0", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "AdvancedJsonRpc\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "A more advanced JSONRPC implementation", - "support": { - "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", - "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" - }, - "time": "2021-06-11T22:34:44+00:00" - }, - { - "name": "felixfbecker/language-server-protocol", - "version": "v1.5.2", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-language-server-protocol.git", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpstan/phpstan": "*", - "squizlabs/php_codesniffer": "^3.1", - "vimeo/psalm": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "LanguageServerProtocol\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "PHP classes for the Language Server Protocol", - "keywords": [ - "language", - "microsoft", - "php", - "server" - ], - "support": { - "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", - "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2" - }, - "time": "2022-03-02T22:36:06+00:00" - }, - { - "name": "laminas/laminas-coding-standard", - "version": "2.4.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-coding-standard.git", - "reference": "eb076dd86aa93dd424856b150c9b6f76c1fdfabc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/eb076dd86aa93dd424856b150c9b6f76c1fdfabc", - "reference": "eb076dd86aa93dd424856b150c9b6f76c1fdfabc", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", - "php": "^7.4 || ^8.0", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.6", - "webimpress/coding-standard": "^1.2" - }, - "conflict": { - "phpstan/phpdoc-parser": ">=1.6.0" - }, - "type": "phpcodesniffer-standard", - "autoload": { - "psr-4": { - "LaminasCodingStandard\\": "src/LaminasCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Laminas Coding Standard", - "homepage": "https://laminas.dev", - "keywords": [ - "Coding Standard", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-coding-standard/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-coding-standard/issues", - "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", - "source": "https://github.com/laminas/laminas-coding-standard" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-08-24T17:45:47+00:00" - }, - { - "name": "laminas/laminas-db", - "version": "2.15.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-db.git", - "reference": "1125ef2e55108bdfcc1f0030d3a0f9b895e09606" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-db/zipball/1125ef2e55108bdfcc1f0030d3a0f9b895e09606", - "reference": "1125ef2e55108bdfcc1f0030d3a0f9b895e09606", - "shasum": "" - }, - "require": { - "laminas/laminas-stdlib": "^3.7.1", - "php": "^7.3 || ~8.0.0 || ~8.1.0" - }, - "conflict": { - "zendframework/zend-db": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.2.1", - "laminas/laminas-eventmanager": "^3.4.0", - "laminas/laminas-hydrator": "^3.2 || ^4.3", - "laminas/laminas-servicemanager": "^3.7.0", - "phpunit/phpunit": "^9.5.19" - }, - "suggest": { - "laminas/laminas-eventmanager": "Laminas\\EventManager component", - "laminas/laminas-hydrator": "(^3.2 || ^4.3) Laminas\\Hydrator component for using HydratingResultSets", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Db", - "config-provider": "Laminas\\Db\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Db\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", - "homepage": "https://laminas.dev", - "keywords": [ - "db", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-db/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-db/issues", - "rss": "https://github.com/laminas/laminas-db/releases.atom", - "source": "https://github.com/laminas/laminas-db" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-04-11T13:26:20+00:00" - }, - { - "name": "laminas/laminas-escaper", - "version": "2.12.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-escaper.git", - "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490", - "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-mbstring": "*", - "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-escaper": "*" - }, - "require-dev": { - "infection/infection": "^0.26.6", - "laminas/laminas-coding-standard": "~2.4.0", - "maglnet/composer-require-checker": "^3.8.0", - "phpunit/phpunit": "^9.5.18", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.22.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Escaper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", - "homepage": "https://laminas.dev", - "keywords": [ - "escaper", - "laminas" - ], - "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" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-10T10:11:09+00:00" - }, - { - "name": "laminas/laminas-eventmanager", - "version": "3.6.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-eventmanager.git", - "reference": "3f1afbad86cd34a431fdc069f265cfe6f8fc8308" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-eventmanager/zipball/3f1afbad86cd34a431fdc069f265cfe6f8fc8308", - "reference": "3f1afbad86cd34a431fdc069f265cfe6f8fc8308", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "container-interop/container-interop": "<1.2", - "zendframework/zend-eventmanager": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-stdlib": "^3.15", - "phpbench/phpbench": "^1.2.6", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.17.0", - "psr/container": "^1.1.2 || ^2.0.2", - "vimeo/psalm": "^4.28" - }, - "suggest": { - "laminas/laminas-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature", - "psr/container": "^1.1.2 || ^2.0.2, to use the lazy listeners feature" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\EventManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Trigger and listen to events within a PHP application", - "homepage": "https://laminas.dev", - "keywords": [ - "event", - "eventmanager", - "events", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-eventmanager/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-eventmanager/issues", - "rss": "https://github.com/laminas/laminas-eventmanager/releases.atom", - "source": "https://github.com/laminas/laminas-eventmanager" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-11T12:46:13+00:00" - }, - { - "name": "laminas/laminas-filter", - "version": "2.28.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-filter.git", - "reference": "b0290636e88083acb42dba7b883aeaa16a60244f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-filter/zipball/b0290636e88083acb42dba7b883aeaa16a60244f", - "reference": "b0290636e88083acb42dba7b883aeaa16a60244f", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "laminas/laminas-servicemanager": "^3.14.0", - "laminas/laminas-stdlib": "^3.13.0", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "laminas/laminas-validator": "<2.10.1", - "zendframework/zend-filter": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-crypt": "^3.9", - "laminas/laminas-uri": "^2.10", - "pear/archive_tar": "^1.4.14", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.3", - "psr/http-factory": "^1.0.1", - "vimeo/psalm": "^4.30" - }, - "suggest": { - "laminas/laminas-crypt": "Laminas\\Crypt component, for encryption filters", - "laminas/laminas-i18n": "Laminas\\I18n component for filters depending on i18n functionality", - "laminas/laminas-uri": "Laminas\\Uri component, for the UriNormalize filter", - "psr/http-factory-implementation": "psr/http-factory-implementation, for creating file upload instances when consuming PSR-7 in file upload filters" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Filter", - "config-provider": "Laminas\\Filter\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Filter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Programmatically filter and normalize data and files", - "homepage": "https://laminas.dev", - "keywords": [ - "filter", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-filter/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-filter/issues", - "rss": "https://github.com/laminas/laminas-filter/releases.atom", - "source": "https://github.com/laminas/laminas-filter" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-11-07T20:46:55+00:00" - }, - { - "name": "laminas/laminas-http", - "version": "2.17.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-http.git", - "reference": "ac4588d698c93b56bb7c0608d9a7537a3f057239" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-http/zipball/ac4588d698c93b56bb7c0608d9a7537a3f057239", - "reference": "ac4588d698c93b56bb7c0608d9a7537a3f057239", - "shasum": "" - }, - "require": { - "laminas/laminas-loader": "^2.8", - "laminas/laminas-stdlib": "^3.6", - "laminas/laminas-uri": "^2.9.1", - "laminas/laminas-validator": "^2.15", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-http": "*" - }, - "require-dev": { - "ext-curl": "*", - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "^9.5.25" - }, - "suggest": { - "paragonie/certainty": "For automated management of cacert.pem" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Http\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests", - "homepage": "https://laminas.dev", - "keywords": [ - "http", - "http client", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-http/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-http/issues", - "rss": "https://github.com/laminas/laminas-http/releases.atom", - "source": "https://github.com/laminas/laminas-http" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-16T15:51:48+00:00" - }, - { - "name": "laminas/laminas-i18n", - "version": "2.19.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-i18n.git", - "reference": "ebabca3a6398fc872127bc69a51bda5afc720d67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-i18n/zipball/ebabca3a6398fc872127bc69a51bda5afc720d67", - "reference": "ebabca3a6398fc872127bc69a51bda5afc720d67", - "shasum": "" - }, - "require": { - "ext-intl": "*", - "laminas/laminas-servicemanager": "^3.14.0", - "laminas/laminas-stdlib": "^2.7 || ^3.0", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "laminas/laminas-view": "<2.20.0", - "phpspec/prophecy": "<1.9.0", - "zendframework/zend-i18n": "*" - }, - "require-dev": { - "laminas/laminas-cache": "^3.6", - "laminas/laminas-cache-storage-adapter-memory": "^2.1", - "laminas/laminas-cache-storage-deprecated-factory": "^1.0.1", - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-config": "^3.7", - "laminas/laminas-eventmanager": "^3.5.0", - "laminas/laminas-filter": "^2.21", - "laminas/laminas-validator": "^2.25", - "laminas/laminas-view": "^2.23", - "phpunit/phpunit": "^9.5.25", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.28" - }, - "suggest": { - "laminas/laminas-cache": "You should install this package to cache the translations", - "laminas/laminas-config": "You should install this package to use the INI translation format", - "laminas/laminas-eventmanager": "You should install this package to use the events in the translator", - "laminas/laminas-filter": "You should install this package to use the provided filters", - "laminas/laminas-i18n-resources": "This package provides validator and captcha translations", - "laminas/laminas-validator": "You should install this package to use the provided validators", - "laminas/laminas-view": "You should install this package to use the provided view helpers" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\I18n", - "config-provider": "Laminas\\I18n\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\I18n\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Provide translations for your application, and filter and validate internationalized values", - "homepage": "https://laminas.dev", - "keywords": [ - "i18n", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-i18n/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-i18n/issues", - "rss": "https://github.com/laminas/laminas-i18n/releases.atom", - "source": "https://github.com/laminas/laminas-i18n" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-10T15:48:56+00:00" - }, - { - "name": "laminas/laminas-loader", - "version": "2.9.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-loader.git", - "reference": "51ed9c3fa42d1098a9997571730c0cbf42d078d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/51ed9c3fa42d1098a9997571730c0cbf42d078d3", - "reference": "51ed9c3fa42d1098a9997571730c0cbf42d078d3", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-loader": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "~9.5.25" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Loader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Autoloading and plugin loading strategies", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "loader" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-loader/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-loader/issues", - "rss": "https://github.com/laminas/laminas-loader/releases.atom", - "source": "https://github.com/laminas/laminas-loader" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-16T12:50:49+00:00" - }, - { - "name": "laminas/laminas-session", - "version": "2.13.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-session.git", - "reference": "9f8a6077dd22b3b253583b1be84ddd5bf6fa1ef4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-session/zipball/9f8a6077dd22b3b253583b1be84ddd5bf6fa1ef4", - "reference": "9f8a6077dd22b3b253583b1be84ddd5bf6fa1ef4", - "shasum": "" - }, - "require": { - "laminas/laminas-eventmanager": "^3.5", - "laminas/laminas-servicemanager": "^3.15.1", - "laminas/laminas-stdlib": "^3.10.1", - "php": "^7.4 || ~8.0.0 || ~8.1.0" - }, - "conflict": { - "zendframework/zend-session": "*" - }, - "require-dev": { - "laminas/laminas-cache": "^3.1.3", - "laminas/laminas-cache-storage-adapter-memory": "^2.0.0", - "laminas/laminas-coding-standard": "~2.3.0", - "laminas/laminas-db": "^2.13.4", - "laminas/laminas-http": "^2.15", - "laminas/laminas-validator": "^2.15", - "mongodb/mongodb": "~1.12.0", - "php-mock/php-mock-phpunit": "^1.1.2 || ^2.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5.9", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.24.0" - }, - "suggest": { - "laminas/laminas-cache": "Laminas\\Cache component", - "laminas/laminas-db": "Laminas\\Db component", - "laminas/laminas-http": "Laminas\\Http component", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component", - "laminas/laminas-validator": "Laminas\\Validator component", - "mongodb/mongodb": "If you want to use the MongoDB session save handler" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Session", - "config-provider": "Laminas\\Session\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Session\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Object-oriented interface to PHP sessions and storage", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "session" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-session/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-session/issues", - "rss": "https://github.com/laminas/laminas-session/releases.atom", - "source": "https://github.com/laminas/laminas-session" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-07-22T10:26:33+00:00" - }, - { - "name": "laminas/laminas-uri", - "version": "2.10.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-uri.git", - "reference": "663b050294945c7345cc3a61f3ca661d5f9e1f80" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-uri/zipball/663b050294945c7345cc3a61f3ca661d5f9e1f80", - "reference": "663b050294945c7345cc3a61f3ca661d5f9e1f80", - "shasum": "" - }, - "require": { - "laminas/laminas-escaper": "^2.9", - "laminas/laminas-validator": "^2.15", - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "conflict": { - "zendframework/zend-uri": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "^9.5.25" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Uri\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "A component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "uri" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-uri/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-uri/issues", - "rss": "https://github.com/laminas/laminas-uri/releases.atom", - "source": "https://github.com/laminas/laminas-uri" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-10-16T15:02:45+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "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" - }, - "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.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "netresearch/jsonmapper", - "version": "v4.0.0", - "source": { - "type": "git", - "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", - "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", - "squizlabs/php_codesniffer": "~3.5" - }, - "type": "library", - "autoload": { - "psr-0": { - "JsonMapper": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "OSL-3.0" - ], - "authors": [ - { - "name": "Christian Weiske", - "email": "cweiske@cweiske.de", - "homepage": "http://github.com/cweiske/jsonmapper/", - "role": "Developer" - } - ], - "description": "Map nested JSON structures onto PHP classes", - "support": { - "email": "cweiske@cweiske.de", - "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" - }, - "time": "2020-12-01T19:48:11+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-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/v4.15.1" - }, - "time": "2022-09-04T07:30:47+00:00" - }, - { - "name": "openlss/lib-array2xml", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/nullivex/lib-array2xml.git", - "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", - "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "autoload": { - "psr-0": { - "LSS": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Bryan Tong", - "email": "bryan@nullivex.com", - "homepage": "https://www.nullivex.com" - }, - { - "name": "Tony Butler", - "email": "spudz76@gmail.com", - "homepage": "https://www.nullivex.com" - } - ], - "description": "Array2XML conversion library credit to lalit.org", - "homepage": "https://www.nullivex.com", - "keywords": [ - "array", - "array conversion", - "xml", - "xml conversion" - ], - "support": { - "issues": "https://github.com/nullivex/lib-array2xml/issues", - "source": "https://github.com/nullivex/lib-array2xml/tree/master" - }, - "time": "2019-03-29T20:06:56+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "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.3" - }, - "time": "2021-07-20T11:28:43+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.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "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": "account@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.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "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.6.2" - }, - "time": "2022-10-14T12:47:21+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "981cc368a216c988e862a75e526b6076987d1b50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50", - "reference": "981cc368a216c988e862a75e526b6076987d1b50", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "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/1.5.1" - }, - "time": "2022-05-05T11:32:40+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.18", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/12fddc491826940cf9b7e88ad9664cf51f0f6d0a", - "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "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" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.2-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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.18" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-10-27T13:35:33+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-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", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.26", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/851867efcbb6a1b992ec515c71cdcf20d895e9d2", - "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "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.13", - "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" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.5-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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.26" - }, - "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": "2022-10-28T06:00:21+00:00" - }, - { - "name": "psalm/plugin-phpunit", - "version": "0.18.3", - "source": { - "type": "git", - "url": "https://github.com/psalm/psalm-plugin-phpunit.git", - "reference": "057c1cdf7546c1e427f6fd83b635d0cc18c252bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/057c1cdf7546c1e427f6fd83b635d0cc18c252bf", - "reference": "057c1cdf7546c1e427f6fd83b635d0cc18c252bf", - "shasum": "" - }, - "require": { - "composer/package-versions-deprecated": "^1.10", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "ext-simplexml": "*", - "php": "^7.1 || ^8.0", - "vimeo/psalm": "dev-master || dev-4.x || ^4.5 || ^5@beta" - }, - "conflict": { - "phpunit/phpunit": "<7.5" - }, - "require-dev": { - "codeception/codeception": "^4.0.3", - "php": "^7.3 || ^8.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0", - "squizlabs/php_codesniffer": "^3.3.1", - "weirdan/codeception-psalm-module": "^0.11.0", - "weirdan/prophecy-shim": "^1.0 || ^2.0" - }, - "type": "psalm-plugin", - "extra": { - "psalm": { - "pluginClass": "Psalm\\PhpUnitPlugin\\Plugin" - } - }, - "autoload": { - "psr-4": { - "Psalm\\PhpUnitPlugin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Brown", - "email": "github@muglug.com" - } - ], - "description": "Psalm plugin for PHPUnit", - "support": { - "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", - "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.18.3" - }, - "time": "2022-11-03T18:17:28+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.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": "http://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/tree/master" - }, - "time": "2020-06-29T06:28:15+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.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": "http://www.php-fig.org/" - } - ], - "description": "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/tree/master" - }, - "time": "2019-04-30T12:38:16+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.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": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/log", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", - "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.0" - }, - "time": "2021-07-14T16:46:02+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "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": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-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": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-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 types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "7.2.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phing/phing": "2.17.3", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.7.1", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2022-05-25T10:58:12+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "symfony/console", - "version": "v6.0.15", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "b0b910724a0a0326b4481e4f8a30abb2dd442efb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/b0b910724a0a0326b4481e4f8a30abb2dd442efb", - "reference": "b0b910724a0a0326b4481e4f8a30abb2dd442efb", - "shasum": "" - }, - "require": { - "php": ">=8.0.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.4|^6.0" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v6.0.15" - }, - "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": "2022-10-26T21:42:20+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "shasum": "" - }, - "require": { - "php": ">=8.0.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" - }, - "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": "2022-01-02T09:55:41+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "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" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "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/polyfill-php80/tree/v1.27.0" - }, - "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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v2.5.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" - }, - "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": "2022-05-30T19:17:29+00:00" - }, - { - "name": "symfony/string", - "version": "v6.0.15", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "51ac0fa0ccf132a00519b87c97e8f775fa14e771" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/51ac0fa0ccf132a00519b87c97e8f775fa14e771", - "reference": "51ac0fa0ccf132a00519b87c97e8f775fa14e771", - "shasum": "" - }, - "require": { - "php": ">=8.0.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.0" - }, - "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.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", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v6.0.15" - }, - "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": "2022-10-10T09:34:08+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "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" - } - ], - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "vimeo/psalm", - "version": "4.30.0", - "source": { - "type": "git", - "url": "https://github.com/vimeo/psalm.git", - "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/d0bc6e25d89f649e4f36a534f330f8bb4643dd69", - "reference": "d0bc6e25d89f649e4f36a534f330f8bb4643dd69", - "shasum": "" - }, - "require": { - "amphp/amp": "^2.4.2", - "amphp/byte-stream": "^1.5", - "composer/package-versions-deprecated": "^1.8.0", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^1.1 || ^2.0 || ^3.0", - "dnoegel/php-xdg-base-dir": "^0.1.1", - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*", - "felixfbecker/advanced-json-rpc": "^3.0.3", - "felixfbecker/language-server-protocol": "^1.5", - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "nikic/php-parser": "^4.13", - "openlss/lib-array2xml": "^1.0", - "php": "^7.1|^8", - "sebastian/diff": "^3.0 || ^4.0", - "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0", - "symfony/polyfill-php80": "^1.25", - "webmozart/path-util": "^2.3" - }, - "provide": { - "psalm/psalm": "self.version" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.2", - "brianium/paratest": "^4.0||^6.0", - "ext-curl": "*", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpdocumentor/reflection-docblock": "^5", - "phpmyadmin/sql-parser": "5.1.0||dev-master", - "phpspec/prophecy": ">=1.9.0", - "phpstan/phpdoc-parser": "1.2.* || 1.6.4", - "phpunit/phpunit": "^9.0", - "psalm/plugin-phpunit": "^0.16", - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.5", - "symfony/process": "^4.3 || ^5.0 || ^6.0", - "weirdan/prophecy-shim": "^1.0 || ^2.0" - }, - "suggest": { - "ext-curl": "In order to send data to shepherd", - "ext-igbinary": "^2.0.5 is required, used to serialize caching data" - }, - "bin": [ - "psalm", - "psalm-language-server", - "psalm-plugin", - "psalm-refactor", - "psalter" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev", - "dev-3.x": "3.x-dev", - "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions.php", - "src/spl_object_id.php" - ], - "psr-4": { - "Psalm\\": "src/Psalm/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthew Brown" - } - ], - "description": "A static analysis tool for finding errors in PHP applications", - "keywords": [ - "code", - "inspection", - "php" - ], - "support": { - "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm/tree/4.30.0" - }, - "time": "2022-11-06T20:37:08+00:00" - }, - { - "name": "webimpress/coding-standard", - "version": "1.2.4", - "source": { - "type": "git", - "url": "https://github.com/webimpress/coding-standard.git", - "reference": "cd0c4b0b97440c337c1f7da17b524674ca2f9ca9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/cd0c4b0b97440c337c1f7da17b524674ca2f9ca9", - "reference": "cd0c4b0b97440c337c1f7da17b524674ca2f9ca9", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "squizlabs/php_codesniffer": "^3.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.13" - }, - "type": "phpcodesniffer-standard", - "extra": { - "dev-master": "1.2.x-dev", - "dev-develop": "1.3.x-dev" - }, - "autoload": { - "psr-4": { - "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "description": "Webimpress Coding Standard", - "keywords": [ - "Coding Standard", - "PSR-2", - "phpcs", - "psr-12", - "webimpress" - ], - "support": { - "issues": "https://github.com/webimpress/coding-standard/issues", - "source": "https://github.com/webimpress/coding-standard/tree/1.2.4" - }, - "funding": [ - { - "url": "https://github.com/michalbundyra", - "type": "github" - } - ], - "time": "2022-02-15T19:52:12+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" - }, - { - "name": "webmozart/path-util", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/path-util.git", - "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", - "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "webmozart/assert": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\PathUtil\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", - "support": { - "issues": "https://github.com/webmozart/path-util/issues", - "source": "https://github.com/webmozart/path-util/tree/2.3.0" - }, - "abandoned": "symfony/filesystem", - "time": "2015-12-17T08:42:14+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "platform-dev": [], - "platform-overrides": { - "php": "8.0.99" - }, - "plugin-api-version": "2.3.0" -} diff --git a/lib/laminas/laminas-validator/renovate.json b/lib/laminas/laminas-validator/renovate.json deleted file mode 100644 index 060b1d1a2..000000000 --- a/lib/laminas/laminas-validator/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "local>laminas/.github:renovate-config" - ] -} diff --git a/lib/laminas/laminas-validator/src/AbstractValidator.php b/lib/laminas/laminas-validator/src/AbstractValidator.php deleted file mode 100644 index 0012126ce..000000000 --- a/lib/laminas/laminas-validator/src/AbstractValidator.php +++ /dev/null @@ -1,620 +0,0 @@ -, - * messageTemplates: array, - * messageVariables: array, - * translator: Translator\TranslatorInterface|null, - * translatorTextDomain: string|null, - * translatorEnabled: bool, - * valueObscured: bool, - * } - * @property array $options - * @property array $messageTemplates - * @property array $messageVariables - */ -abstract class AbstractValidator implements - Translator\TranslatorAwareInterface, - ValidatorInterface -{ - /** - * The value to be validated - * - * @var mixed - */ - protected $value; - - /** - * Default translation object for all validate objects - * - * @var Translator\TranslatorInterface - */ - protected static $defaultTranslator; - - /** - * Default text domain to be used with translator - * - * @var string - */ - protected static $defaultTranslatorTextDomain = 'default'; - - /** - * Limits the maximum returned length of an error message - * - * @var int - */ - protected static $messageLength = -1; - - /** @var AbstractOptions&array */ - protected $abstractOptions = [ - 'messages' => [], // Array of validation failure messages - 'messageTemplates' => [], // Array of validation failure message templates - 'messageVariables' => [], // Array of additional variables available for validation failure messages - 'translator' => null, // Translation object to used -> Translator\TranslatorInterface - 'translatorTextDomain' => null, // Translation text domain - 'translatorEnabled' => true, // Is translation enabled? - 'valueObscured' => false, // Flag indicating whether value should be obfuscated in error messages - ]; - - /** - * Abstract constructor for all validators - * A validator should accept following parameters: - * - nothing f.e. Validator() - * - one or multiple scalar values f.e. Validator($first, $second, $third) - * - an array f.e. Validator(array($first => 'first', $second => 'second', $third => 'third')) - * - an instance of Traversable f.e. Validator($config_instance) - * - * @param array|Traversable $options - */ - public function __construct($options = null) - { - // The abstract constructor allows no scalar values - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - - /** @psalm-suppress RedundantConditionGivenDocblockType */ - if (isset($this->messageTemplates) && is_array($this->messageTemplates)) { - $this->abstractOptions['messageTemplates'] = $this->messageTemplates; - } - - /** @psalm-suppress RedundantConditionGivenDocblockType */ - if (isset($this->messageVariables) && is_array($this->messageVariables)) { - $this->abstractOptions['messageVariables'] = $this->messageVariables; - } - - if (is_array($options)) { - $this->setOptions($options); - } - } - - /** - * Returns an option - * - * @param string $option Option to be returned - * @return mixed Returned option - * @throws Exception\InvalidArgumentException - */ - public function getOption($option) - { - if (array_key_exists($option, $this->abstractOptions)) { - return $this->abstractOptions[$option]; - } - - /** @psalm-suppress RedundantConditionGivenDocblockType */ - if (isset($this->options) && array_key_exists($option, $this->options)) { - return $this->options[$option]; - } - - throw new Exception\InvalidArgumentException("Invalid option '$option'"); - } - - /** - * Returns all available options - * - * @return array Array with all available options - */ - public function getOptions() - { - $result = $this->abstractOptions; - /** @psalm-suppress RedundantConditionGivenDocblockType */ - if (isset($this->options) && is_array($this->options)) { - $result += $this->options; - } - return $result; - } - - /** - * Sets one or multiple options - * - * @param array|Traversable $options Options to set - * @return $this Provides fluid interface - * @throws Exception\InvalidArgumentException If $options is not an array or Traversable. - */ - public function setOptions($options = []) - { - /** @psalm-suppress DocblockTypeContradiction */ - if (! is_array($options) && ! $options instanceof Traversable) { - throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable'); - } - - /** - * @psalm-suppress RedundantConditionGivenDocblockType - * @psalm-var mixed $option - */ - foreach ($options as $name => $option) { - $fname = 'set' . ucfirst($name); - $fname2 = 'is' . ucfirst($name); - if (($name !== 'setOptions') && method_exists($this, $name)) { - $this->{$name}($option); - } elseif (($fname !== 'setOptions') && method_exists($this, $fname)) { - $this->{$fname}($option); - } elseif (method_exists($this, $fname2)) { - $this->{$fname2}($option); - } elseif (isset($this->options) && is_array($this->options)) { - $this->options[$name] = $option; - } else { - $this->abstractOptions[$name] = $option; - } - } - - return $this; - } - - /** - * Returns array of validation failure messages - * - * @return array - */ - public function getMessages() - { - return array_unique($this->abstractOptions['messages'], SORT_REGULAR); - } - - /** - * Invoke as command - * - * @return bool - */ - public function __invoke(mixed $value) - { - return $this->isValid($value); - } - - /** - * Returns an array of the names of variables that are used in constructing validation failure messages - * - * @return list - */ - public function getMessageVariables() - { - return array_keys($this->abstractOptions['messageVariables']); - } - - /** - * Returns the message templates from the validator - * - * @return array - */ - public function getMessageTemplates() - { - return $this->abstractOptions['messageTemplates']; - } - - /** - * Sets the validation failure message template for a particular key - * - * @param string $messageString - * @param string|null $messageKey OPTIONAL - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function setMessage($messageString, $messageKey = null) - { - if ($messageKey === null) { - $keys = array_keys($this->abstractOptions['messageTemplates']); - foreach ($keys as $key) { - $this->setMessage($messageString, $key); - } - return $this; - } - - if (! isset($this->abstractOptions['messageTemplates'][$messageKey])) { - throw new Exception\InvalidArgumentException("No message template exists for key '$messageKey'"); - } - - $this->abstractOptions['messageTemplates'][$messageKey] = $messageString; - return $this; - } - - /** - * Sets validation failure message templates given as an array, where the array keys are the message keys, - * and the array values are the message template strings. - * - * @param array $messages - * @return $this - */ - public function setMessages(array $messages) - { - foreach ($messages as $key => $message) { - $this->setMessage($message, $key); - } - return $this; - } - - /** - * Magic function returns the value of the requested property, if and only if it is the value or a - * message variable. - * - * @param string $property - * @return mixed - * @throws Exception\InvalidArgumentException - */ - public function __get($property) - { - if ($property === 'value') { - return $this->value; - } - - if (array_key_exists($property, $this->abstractOptions['messageVariables'])) { - /** @psalm-var mixed $result */ - $result = $this->abstractOptions['messageVariables'][$property]; - if (is_array($result)) { - return $this->{key($result)}[current($result)]; - } - return $this->{$result}; - } - - /** @psalm-suppress RedundantConditionGivenDocblockType */ - if (isset($this->messageVariables) && array_key_exists($property, $this->messageVariables)) { - /** @psalm-var mixed $result */ - $result = $this->{$this->messageVariables[$property]}; - if (is_array($result)) { - return $this->{key($result)}[current($result)]; - } - return $this->{$result}; - } - - throw new Exception\InvalidArgumentException("No property exists by the name '$property'"); - } - - /** - * Constructs and returns a validation failure message with the given message key and value. - * - * Returns null if and only if $messageKey does not correspond to an existing template. - * - * If a translator is available and a translation exists for $messageKey, - * the translation will be used. - * - * @param string $messageKey - * @param string|array|object $value - * @return null|string - */ - protected function createMessage($messageKey, $value) - { - if (! isset($this->abstractOptions['messageTemplates'][$messageKey])) { - return null; - } - - $message = $this->abstractOptions['messageTemplates'][$messageKey]; - - $message = $this->translateMessage($messageKey, $message); - - if (is_object($value)) { - $value = method_exists($value, '__toString') - ? (string) $value - : $value::class . ' object'; - } elseif (is_array($value)) { - $value = var_export($value, true); - } else { - /** @psalm-suppress RedundantCastGivenDocblockType $value */ - $value = (string) $value; - } - - if ($this->isValueObscured()) { - $value = str_repeat('*', strlen($value)); - } - - $message = str_replace('%value%', $value, $message); - foreach ($this->abstractOptions['messageVariables'] as $ident => $property) { - if (is_array($property)) { - $value = $this->{key($property)}[current($property)]; - if (is_array($value)) { - $value = '[' . implode(', ', $value) . ']'; - } - } else { - $value = $this->$property; - } - $message = str_replace("%$ident%", (string) $value, $message); - } - - $length = self::getMessageLength(); - if (($length > -1) && (strlen($message) > $length)) { - $message = substr($message, 0, $length - 3) . '...'; - } - - return $message; - } - - /** - * @param string|null $messageKey - * @param null|string|array|object $value OPTIONAL - * @return void - */ - protected function error($messageKey, $value = null) - { - if ($messageKey === null) { - $keys = array_keys($this->abstractOptions['messageTemplates']); - $messageKey = current($keys); - } - - if ($value === null) { - /** @psalm-var string|array|object $value */ - $value = $this->value; - } - - $message = $this->createMessage($messageKey, $value); - if (! is_string($message)) { - return; - } - - $this->abstractOptions['messages'][$messageKey] = $message; - } - - /** - * Returns the validation value - * - * @return mixed Value to be validated - */ - protected function getValue() - { - return $this->value; - } - - /** - * Sets the value to be validated and clears the messages and errors arrays - * - * @return void - */ - protected function setValue(mixed $value) - { - $this->value = $value; - $this->abstractOptions['messages'] = []; - } - - /** - * Set flag indicating whether or not value should be obfuscated in messages - * - * @param bool $flag - * @return $this - */ - public function setValueObscured($flag) - { - /** @psalm-suppress RedundantCastGivenDocblockType */ - $this->abstractOptions['valueObscured'] = (bool) $flag; - return $this; - } - - /** - * Retrieve flag indicating whether or not value should be obfuscated in - * messages - * - * @return bool - */ - public function isValueObscured() - { - return $this->abstractOptions['valueObscured']; - } - - /** - * Set translation object - * - * @param string $textDomain (optional) - * @return $this - * @throws Exception\InvalidArgumentException - */ - public function setTranslator(?Translator\TranslatorInterface $translator = null, $textDomain = null) - { - $this->abstractOptions['translator'] = $translator; - if (null !== $textDomain) { - $this->setTranslatorTextDomain($textDomain); - } - return $this; - } - - /** - * Return translation object - * - * @return Translator\TranslatorInterface|null - */ - public function getTranslator() - { - if (! $this->isTranslatorEnabled()) { - return null; - } - - if (null === $this->abstractOptions['translator']) { - $this->abstractOptions['translator'] = self::getDefaultTranslator(); - } - - return $this->abstractOptions['translator']; - } - - /** - * Does this validator have its own specific translator? - * - * @return bool - */ - public function hasTranslator() - { - return (bool) $this->abstractOptions['translator']; - } - - /** - * Set translation text domain - * - * @param string $textDomain - * @return $this - */ - public function setTranslatorTextDomain($textDomain = 'default') - { - $this->abstractOptions['translatorTextDomain'] = $textDomain; - return $this; - } - - /** - * Return the translation text domain - * - * @return string - */ - public function getTranslatorTextDomain() - { - if (null === $this->abstractOptions['translatorTextDomain']) { - $this->abstractOptions['translatorTextDomain'] = - self::getDefaultTranslatorTextDomain(); - } - return $this->abstractOptions['translatorTextDomain']; - } - - /** - * Set default translation object for all validate objects - * - * @param string $textDomain (optional) - * @return void - * @throws Exception\InvalidArgumentException - */ - public static function setDefaultTranslator(?Translator\TranslatorInterface $translator = null, $textDomain = null) - { - static::$defaultTranslator = $translator; - if (null !== $textDomain) { - self::setDefaultTranslatorTextDomain($textDomain); - } - } - - /** - * Get default translation object for all validate objects - * - * @return Translator\TranslatorInterface|null - */ - public static function getDefaultTranslator() - { - return static::$defaultTranslator; - } - - /** - * Is there a default translation object set? - * - * @return bool - */ - public static function hasDefaultTranslator() - { - return (bool) static::$defaultTranslator; - } - - /** - * Set default translation text domain for all validate objects - * - * @param string $textDomain - * @return void - */ - public static function setDefaultTranslatorTextDomain($textDomain = 'default') - { - static::$defaultTranslatorTextDomain = $textDomain; - } - - /** - * Get default translation text domain for all validate objects - * - * @return string - */ - public static function getDefaultTranslatorTextDomain() - { - return static::$defaultTranslatorTextDomain; - } - - /** - * Indicate whether or not translation should be enabled - * - * @param bool $enabled - * @return $this - */ - public function setTranslatorEnabled($enabled = true) - { - /** @psalm-suppress RedundantCastGivenDocblockType */ - $this->abstractOptions['translatorEnabled'] = (bool) $enabled; - return $this; - } - - /** - * Is translation enabled? - * - * @return bool - */ - public function isTranslatorEnabled() - { - return $this->abstractOptions['translatorEnabled']; - } - - /** - * Returns the maximum allowed message length - * - * @return int - */ - public static function getMessageLength() - { - return static::$messageLength; - } - - /** - * Sets the maximum allowed message length - * - * @param int $length - * @return void - */ - public static function setMessageLength($length = -1) - { - static::$messageLength = $length; - } - - /** - * Translate a validation message - * - * @param string $messageKey - * @param string $message - * @return string - */ - protected function translateMessage($messageKey, $message) - { - $translator = $this->getTranslator(); - if (! $translator) { - return $message; - } - - return $translator->translate($message, $this->getTranslatorTextDomain()); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode.php b/lib/laminas/laminas-validator/src/Barcode.php deleted file mode 100644 index f14cb8209..000000000 --- a/lib/laminas/laminas-validator/src/Barcode.php +++ /dev/null @@ -1,197 +0,0 @@ - */ - protected $messageTemplates = [ - self::FAILED => 'The input failed checksum validation', - self::INVALID_CHARS => 'The input contains invalid characters', - self::INVALID_LENGTH => 'The input should have a length of %length% characters', - self::INVALID => 'Invalid type given. String expected', - ]; - - /** - * Additional variables available for validation failure messages - * - * @var array> - */ - protected $messageVariables = [ - 'length' => ['options' => 'length'], - ]; - - /** @var array */ - protected $options = [ - 'adapter' => null, // Barcode adapter Laminas\Validator\Barcode\AbstractAdapter - 'options' => null, // Options for this adapter - 'length' => null, - 'useChecksum' => null, - ]; - - /** - * Constructor for barcodes - * - * @param array|string $options Options to use - */ - public function __construct($options = null) - { - if ($options === null) { - $options = []; - } - - if (is_array($options)) { - if (array_key_exists('options', $options)) { - $options['options'] = ['options' => $options['options']]; - } - } elseif ($options instanceof Traversable) { - if (property_exists($options, 'options')) { - $options['options'] = ['options' => $options['options']]; - } - } else { - $options = ['adapter' => $options]; - } - - parent::__construct($options); - } - - /** - * Returns the set adapter - * - * @return Barcode\AbstractAdapter - */ - public function getAdapter() - { - if (! $this->options['adapter'] instanceof Barcode\AdapterInterface) { - $this->setAdapter('Ean13'); - } - - return $this->options['adapter']; - } - - /** - * Sets a new barcode adapter - * - * @param string|Barcode\AbstractAdapter $adapter Barcode adapter to use - * @param array $options Options for this adapter - * @return $this - * @throws Exception\InvalidArgumentException - */ - public function setAdapter($adapter, $options = null) - { - if (is_string($adapter)) { - $adapter = ucfirst(strtolower($adapter)); - $adapter = 'Laminas\\Validator\\Barcode\\' . $adapter; - - if (! class_exists($adapter)) { - throw new Exception\InvalidArgumentException('Barcode adapter matching "' . $adapter . '" not found'); - } - - $adapter = new $adapter($options); - } - - if (! $adapter instanceof Barcode\AdapterInterface) { - throw new Exception\InvalidArgumentException( - sprintf( - 'Adapter %s does not implement Laminas\\Validator\\Barcode\\AdapterInterface', - get_debug_type($adapter) - ) - ); - } - - $this->options['adapter'] = $adapter; - - return $this; - } - - /** - * Returns the checksum option - * - * @return string - */ - public function getChecksum() - { - return $this->getAdapter()->getChecksum(); - } - - /** - * Sets if checksum should be validated, if no value is given the actual setting is returned - * - * @param null|bool $checksum - * @return Barcode\AbstractAdapter|bool - */ - public function useChecksum($checksum = null) - { - return $this->getAdapter()->useChecksum($checksum); - } - - /** - * Defined by Laminas\Validator\ValidatorInterface - * - * Returns true if and only if $value contains a valid barcode - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - $adapter = $this->getAdapter(); - $this->options['length'] = $adapter->getLength(); - $result = $adapter->hasValidLength($value); - if (! $result) { - if (is_array($this->options['length'])) { - $temp = $this->options['length']; - $this->options['length'] = ''; - foreach ($temp as $length) { - $this->options['length'] .= '/'; - $this->options['length'] .= $length; - } - - $this->options['length'] = substr($this->options['length'], 1); - } - - $this->error(self::INVALID_LENGTH); - return false; - } - - $result = $adapter->hasValidCharacters($value); - if (! $result) { - $this->error(self::INVALID_CHARS); - return false; - } - - if ($this->useChecksum(null)) { - $result = $adapter->hasValidChecksum($value); - if (! $result) { - $this->error(self::FAILED); - return false; - } - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/AbstractAdapter.php b/lib/laminas/laminas-validator/src/Barcode/AbstractAdapter.php deleted file mode 100644 index 56a0164d0..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/AbstractAdapter.php +++ /dev/null @@ -1,312 +0,0 @@ - null, // Allowed barcode lengths, integer, array, string - 'characters' => null, // Allowed barcode characters - 'checksum' => null, // Callback to checksum function - 'useChecksum' => true, // Is a checksum value included?, boolean - ]; - - /** - * Checks the length of a barcode - * - * @param string $value The barcode to check for proper length - * @return bool - */ - public function hasValidLength($value) - { - if (! is_string($value)) { - return false; - } - - $fixum = strlen($value); - $length = $this->getLength(); - - if (is_array($length)) { - foreach ($length as $value) { - if ($fixum === $value) { - return true; - } - - if ($value === -1) { - return true; - } - } - - return false; - } - - if ($fixum === $length) { - return true; - } - - if ($length === -1) { - return true; - } - - if ($length === 'even') { - $count = $fixum % 2; - return 0 === $count; - } - - if ($length === 'odd') { - $count = $fixum % 2; - return 1 === $count; - } - - return false; - } - - /** - * Checks for allowed characters within the barcode - * - * @param string $value The barcode to check for allowed characters - * @return bool - */ - public function hasValidCharacters($value) - { - if (! is_string($value)) { - return false; - } - - $characters = $this->getCharacters(); - if ($characters === 128) { - for ($x = 0; $x < 128; ++$x) { - $value = str_replace(chr($x), '', $value); - } - } else { - $chars = str_split($characters); - foreach ($chars as $char) { - $value = str_replace($char, '', $value); - } - } - - if (strlen($value) > 0) { - return false; - } - - return true; - } - - /** - * Validates the checksum - * - * @param string $value The barcode to check the checksum for - * @return bool - */ - public function hasValidChecksum($value) - { - $checksum = $this->getChecksum(); - if (! empty($checksum)) { - if (method_exists($this, $checksum)) { - return $this->$checksum($value); - } - } - - return false; - } - - /** - * Returns the allowed barcode length - * - * @return int|array - */ - public function getLength() - { - return $this->options['length']; - } - - /** - * Returns the allowed characters - * - * @return int|string|array - */ - public function getCharacters() - { - return $this->options['characters']; - } - - /** - * Returns the checksum function name - * - * @return string - */ - public function getChecksum() - { - return $this->options['checksum']; - } - - /** - * Sets the checksum validation method - * - * @param callable $checksum Checksum method to call - * @return $this - */ - protected function setChecksum($checksum) - { - $this->options['checksum'] = $checksum; - return $this; - } - - /** - * Sets the checksum validation, if no value is given, the actual setting is returned - * - * @param bool $check - * @return AbstractAdapter|bool - */ - public function useChecksum($check = null) - { - if ($check === null) { - return $this->options['useChecksum']; - } - - $this->options['useChecksum'] = (bool) $check; - return $this; - } - - /** - * Sets the length of this barcode - * - * @param int|array $length - * @return $this - */ - protected function setLength($length) - { - $this->options['length'] = $length; - return $this; - } - - /** - * Sets the allowed characters of this barcode - * - * @param int $characters - * @return $this - */ - protected function setCharacters($characters) - { - $this->options['characters'] = $characters; - return $this; - } - - /** - * Validates the checksum (Modulo 10) - * GTIN implementation factor 3 - * - * @param string $value The barcode to validate - * @return bool - */ - protected function gtin($value) - { - $barcode = substr($value, 0, -1); - $sum = 0; - $length = strlen($barcode) - 1; - - for ($i = 0; $i <= $length; $i++) { - if (($i % 2) === 0) { - $sum += $barcode[$length - $i] * 3; - } else { - $sum += $barcode[$length - $i]; - } - } - - $calc = $sum % 10; - $checksum = $calc === 0 ? 0 : 10 - $calc; - - return $value[$length + 1] === (string) $checksum; - } - - /** - * Validates the checksum (Modulo 10) - * IDENTCODE implementation factors 9 and 4 - * - * @param string $value The barcode to validate - * @return bool - */ - protected function identcode($value) - { - $barcode = substr($value, 0, -1); - $sum = 0; - $length = strlen($value) - 2; - - for ($i = 0; $i <= $length; $i++) { - if (($i % 2) === 0) { - $sum += $barcode[$length - $i] * 4; - } else { - $sum += $barcode[$length - $i] * 9; - } - } - - $calc = $sum % 10; - $checksum = $calc === 0 ? 0 : 10 - $calc; - - return $value[$length + 1] === (string) $checksum; - } - - /** - * Validates the checksum (Modulo 10) - * CODE25 implementation factor 3 - * - * @param string $value The barcode to validate - * @return bool - */ - protected function code25($value) - { - $barcode = substr($value, 0, -1); - $sum = 0; - $length = strlen($barcode) - 1; - - for ($i = 0; $i <= $length; $i++) { - if (($i % 2) === 0) { - $sum += $barcode[$i] * 3; - } else { - $sum += $barcode[$i]; - } - } - - $calc = $sum % 10; - $checksum = $calc === 0 ? 0 : 10 - $calc; - - return $value[$length + 1] === (string) $checksum; - } - - /** - * Validates the checksum () - * POSTNET implementation - * - * @param string $value The barcode to validate - * @return bool - */ - protected function postnet($value) - { - $checksum = substr($value, -1, 1); - $values = str_split(substr($value, 0, -1)); - - $check = 0; - foreach ($values as $row) { - $check += $row; - } - - $check %= 10; - $check = 10 - $check; - - return (string) $check === $checksum; - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/AdapterInterface.php b/lib/laminas/laminas-validator/src/Barcode/AdapterInterface.php deleted file mode 100644 index 5ccab6103..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/AdapterInterface.php +++ /dev/null @@ -1,59 +0,0 @@ -setLength(-1); - $this->setCharacters('0123456789-$:/.+ABCDTN*E'); - $this->useChecksum(false); - } - - /** - * Checks for allowed characters - * - * @see Laminas\Validator\Barcode.AbstractAdapter::checkChars() - * - * @param string $value - * @return bool - */ - public function hasValidCharacters($value) - { - if (strpbrk($value, 'ABCD')) { - $first = $value[0]; - if (! strpbrk($first, 'ABCD')) { - // Missing start char - return false; - } - - $last = substr($value, -1, 1); - if (! strpbrk($last, 'ABCD')) { - // Missing stop char - return false; - } - - $value = substr($value, 1, -1); - } elseif (strpbrk($value, 'TN*E')) { - $first = $value[0]; - if (! strpbrk($first, 'TN*E')) { - // Missing start char - return false; - } - - $last = substr($value, -1, 1); - if (! strpbrk($last, 'TN*E')) { - // Missing stop char - return false; - } - - $value = substr($value, 1, -1); - } - - $chars = $this->getCharacters(); - $this->setCharacters('0123456789-$:/.+'); - $result = parent::hasValidCharacters($value); - $this->setCharacters($chars); - return $result; - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Code128.php b/lib/laminas/laminas-validator/src/Barcode/Code128.php deleted file mode 100644 index 04d81c9cb..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Code128.php +++ /dev/null @@ -1,733 +0,0 @@ -setLength(-1); - $this->setCharacters([ - 'A' => [ - 0 => ' ', - 1 => '!', - 2 => '"', - 3 => '#', - 4 => '$', - 5 => '%', - 6 => '&', - 7 => "'", - 8 => '(', - 9 => ')', - 10 => '*', - 11 => '+', - 12 => ',', - 13 => '-', - 14 => '.', - 15 => '/', - 16 => '0', - 17 => '1', - 18 => '2', - 19 => '3', - 20 => '4', - 21 => '5', - 22 => '6', - 23 => '7', - 24 => '8', - 25 => '9', - 26 => ':', - 27 => ';', - 28 => '<', - 29 => '=', - 30 => '>', - 31 => '?', - 32 => '@', - 33 => 'A', - 34 => 'B', - 35 => 'C', - 36 => 'D', - 37 => 'E', - 38 => 'F', - 39 => 'G', - 40 => 'H', - 41 => 'I', - 42 => 'J', - 43 => 'K', - 44 => 'L', - 45 => 'M', - 46 => 'N', - 47 => 'O', - 48 => 'P', - 49 => 'Q', - 50 => 'R', - 51 => 'S', - 52 => 'T', - 53 => 'U', - 54 => 'V', - 55 => 'W', - 56 => 'X', - 57 => 'Y', - 58 => 'Z', - 59 => '[', - 60 => '\\', - 61 => ']', - 62 => '^', - 63 => '_', - 64 => 0x00, - 65 => 0x01, - 66 => 0x02, - 67 => 0x03, - 68 => 0x04, - 69 => 0x05, - 70 => 0x06, - 71 => 0x07, - 72 => 0x08, - 73 => 0x09, - 74 => 0x0A, - 75 => 0x0B, - 76 => 0x0C, - 77 => 0x0D, - 78 => 0x0E, - 79 => 0x0F, - 80 => 0x10, - 81 => 0x11, - 82 => 0x12, - 83 => 0x13, - 84 => 0x14, - 85 => 0x15, - 86 => 0x16, - 87 => 0x17, - 88 => 0x18, - 89 => 0x19, - 90 => 0x1A, - 91 => 0x1B, - 92 => 0x1C, - 93 => 0x1D, - 94 => 0x1E, - 95 => 0x1F, - 96 => 'Ç', - 97 => 'ü', - 98 => 'é', - 99 => 'â', - 100 => 'ä', - 101 => 'à', - 102 => 'å', - 103 => '‡', - 104 => 'ˆ', - 105 => '‰', - 106 => 'Š', - ], - 'B' => [ - 0 => ' ', - 1 => '!', - 2 => '"', - 3 => '#', - 4 => '$', - 5 => '%', - 6 => '&', - 7 => "'", - 8 => '(', - 9 => ')', - 10 => '*', - 11 => '+', - 12 => ',', - 13 => '-', - 14 => '.', - 15 => '/', - 16 => '0', - 17 => '1', - 18 => '2', - 19 => '3', - 20 => '4', - 21 => '5', - 22 => '6', - 23 => '7', - 24 => '8', - 25 => '9', - 26 => ':', - 27 => ';', - 28 => '<', - 29 => '=', - 30 => '>', - 31 => '?', - 32 => '@', - 33 => 'A', - 34 => 'B', - 35 => 'C', - 36 => 'D', - 37 => 'E', - 38 => 'F', - 39 => 'G', - 40 => 'H', - 41 => 'I', - 42 => 'J', - 43 => 'K', - 44 => 'L', - 45 => 'M', - 46 => 'N', - 47 => 'O', - 48 => 'P', - 49 => 'Q', - 50 => 'R', - 51 => 'S', - 52 => 'T', - 53 => 'U', - 54 => 'V', - 55 => 'W', - 56 => 'X', - 57 => 'Y', - 58 => 'Z', - 59 => '[', - 60 => '\\', - 61 => ']', - 62 => '^', - 63 => '_', - 64 => '`', - 65 => 'a', - 66 => 'b', - 67 => 'c', - 68 => 'd', - 69 => 'e', - 70 => 'f', - 71 => 'g', - 72 => 'h', - 73 => 'i', - 74 => 'j', - 75 => 'k', - 76 => 'l', - 77 => 'm', - 78 => 'n', - 79 => 'o', - 80 => 'p', - 81 => 'q', - 82 => 'r', - 83 => 's', - 84 => 't', - 85 => 'u', - 86 => 'v', - 87 => 'w', - 88 => 'x', - 89 => 'y', - 90 => 'z', - 91 => '{', - 92 => '|', - 93 => '}', - 94 => '~', - 95 => 0x7F, - 96 => 'Ç', - 97 => 'ü', - 98 => 'é', - 99 => 'â', - 100 => 'ä', - 101 => 'à', - 102 => 'å', - 103 => '‡', - 104 => 'ˆ', - 105 => '‰', - 106 => 'Š', - ], - 'C' => [ - 0 => '00', - 1 => '01', - 2 => '02', - 3 => '03', - 4 => '04', - 5 => '05', - 6 => '06', - 7 => '07', - 8 => '08', - 9 => '09', - 10 => '10', - 11 => '11', - 12 => '12', - 13 => '13', - 14 => '14', - 15 => '15', - 16 => '16', - 17 => '17', - 18 => '18', - 19 => '19', - 20 => '20', - 21 => '21', - 22 => '22', - 23 => '23', - 24 => '24', - 25 => '25', - 26 => '26', - 27 => '27', - 28 => '28', - 29 => '29', - 30 => '30', - 31 => '31', - 32 => '32', - 33 => '33', - 34 => '34', - 35 => '35', - 36 => '36', - 37 => '37', - 38 => '38', - 39 => '39', - 40 => '40', - 41 => '41', - 42 => '42', - 43 => '43', - 44 => '44', - 45 => '45', - 46 => '46', - 47 => '47', - 48 => '48', - 49 => '49', - 50 => '50', - 51 => '51', - 52 => '52', - 53 => '53', - 54 => '54', - 55 => '55', - 56 => '56', - 57 => '57', - 58 => '58', - 59 => '59', - 60 => '60', - 61 => '61', - 62 => '62', - 63 => '63', - 64 => '64', - 65 => '65', - 66 => '66', - 67 => '67', - 68 => '68', - 69 => '69', - 70 => '70', - 71 => '71', - 72 => '72', - 73 => '73', - 74 => '74', - 75 => '75', - 76 => '76', - 77 => '77', - 78 => '78', - 79 => '79', - 80 => '80', - 81 => '81', - 82 => '82', - 83 => '83', - 84 => '84', - 85 => '85', - 86 => '86', - 87 => '87', - 88 => '88', - 89 => '89', - 90 => '90', - 91 => '91', - 92 => '92', - 93 => '93', - 94 => '94', - 95 => '95', - 96 => '96', - 97 => '97', - 98 => '98', - 99 => '99', - 100 => 'ä', - 101 => 'à', - 102 => 'å', - 103 => '‡', - 104 => 'ˆ', - 105 => '‰', - 106 => 'Š', - ], - ]); - $this->setChecksum('code128'); - } - - /** - * @return void - */ - public function setUtf8StringWrapper(StringWrapperInterface $utf8StringWrapper) - { - if (! $utf8StringWrapper->isSupported('UTF-8')) { - throw new Exception\InvalidArgumentException( - 'The string wrapper needs to support UTF-8 character encoding' - ); - } - $this->utf8StringWrapper = $utf8StringWrapper; - } - - /** - * Get the string wrapper supporting UTF-8 character encoding - * - * @return StringWrapperInterface - */ - public function getUtf8StringWrapper() - { - if (! $this->utf8StringWrapper) { - $this->utf8StringWrapper = StringUtils::getWrapper('UTF-8'); - } - return $this->utf8StringWrapper; - } - - /** - * Checks for allowed characters within the barcode - * - * @param string $value The barcode to check for allowed characters - * @return bool - */ - public function hasValidCharacters($value) - { - if (! is_string($value)) { - return false; - } - - // get used string wrapper for UTF-8 character encoding - $strWrapper = $this->getUtf8StringWrapper(); - - // detect starting charset - $set = $this->getCodingSet($value); - $read = $set; - if ($set !== '') { - $value = $strWrapper->substr($value, 1, null); - } - - // process barcode - while ($value !== '' && $value !== false) { - $char = $strWrapper->substr($value, 0, 1); - - switch ($char) { - // Function definition - case 'Ç': - case 'ü': - case 'å': - break; - - // Switch 1 char between A and B - case 'é': - if ($set === 'A') { - $read = 'B'; - break; - } - - if ($set === 'B') { - $read = 'A'; - break; - } - - break; - - // Switch to C - case 'â': - $set = 'C'; - $read = 'C'; - break; - - // Switch to B - case 'ä': - $set = 'B'; - $read = 'B'; - break; - - // Switch to A - case 'à': - $set = 'A'; - $read = 'A'; - break; - - // Doubled start character - case '‡': - case 'ˆ': - case '‰': - return false; - - // Chars after the stop character - case 'Š': - break 2; - - default: - // Does the char exist within the charset to read? - if ($this->ord128($char, $read) === -1) { - return false; - } - - break; - } - - $value = $strWrapper->substr($value, 1, null); - $read = $set; - } - - if ($value !== '' && is_string($value) && $strWrapper->strlen($value) !== 1) { - return false; - } - - return true; - } - - /** - * Validates the checksum () - * - * @param string $value The barcode to validate - * @return bool - */ - protected function code128($value) - { - $sum = 0; - $pos = 1; - $set = $this->getCodingSet($value); - $read = $set; - $usecheck = $this->useChecksum(null); - $strWrapper = $this->getUtf8StringWrapper(); - $char = $strWrapper->substr($value, 0, 1); - if ($char === '‡') { - $sum = 103; - } elseif ($char === 'ˆ') { - $sum = 104; - } elseif ($char === '‰') { - $sum = 105; - } elseif ($usecheck === true) { - // no start value, unable to detect a proper checksum - return false; - } - - $value = $strWrapper->substr($value, 1, null); - while ($strWrapper->strpos($value, 'Š') || ($value !== '')) { - $char = $strWrapper->substr($value, 0, 1); - if ($read === 'C') { - $char = $strWrapper->substr($value, 0, 2); - } - - switch ($char) { - // Function definition - case 'Ç': - case 'ü': - case 'å': - $sum += $pos * $this->ord128($char, $set); - break; - - case 'é': - $sum += $pos * $this->ord128($char, $set); - - if ($set === 'A') { - $read = 'B'; - break; - } - - if ($set === 'B') { - $read = 'A'; - break; - } - - break; - - // Switch to C - case 'â': - $sum += $pos * $this->ord128($char, $set); - $set = 'C'; - $read = 'C'; - break; - - // Switch to B - case 'ä': - $sum += $pos * $this->ord128($char, $set); - $set = 'B'; - $read = 'B'; - break; - - // Switch to A - case 'à': - $sum += $pos * $this->ord128($char, $set); - $set = 'A'; - $read = 'A'; - break; - - case '‡': - case 'ˆ': - case '‰': - return false; - - default: - // Does the char exist within the charset to read? - if ($this->ord128($char, $read) === -1) { - return false; - } - - $sum += $pos * $this->ord128($char, $set); - break; - } - - $value = $strWrapper->substr($value, 1); - ++$pos; - if (($strWrapper->strpos($value, 'Š') === 1) && ($strWrapper->strlen($value) === 2)) { - // break by stop and checksum char - break; - } - $read = $set; - } - - if (($strWrapper->strpos($value, 'Š') !== 1) || ($strWrapper->strlen($value) !== 2)) { - // return false if checksum is not readable and true if no startvalue is detected - return ! $usecheck; - } - - $mod = $sum % 103; - if ($strWrapper->substr($value, 0, 1) === $this->chr128($mod, $set)) { - return true; - } - - return false; - } - - /** - * Returns the coding set for a barcode - * - * @param string $value Barcode - * @return string - */ - protected function getCodingSet($value) - { - $value = $this->getUtf8StringWrapper()->substr($value, 0, 1); - return match ($value) { - '‡' => 'A', - 'ˆ' => 'B', - '‰' => 'C', - default => '', - }; - } - - /** - * Internal method to return the code128 integer from an ascii value - * - * Table A - * ASCII CODE128 - * 32 to 95 == 0 to 63 - * 0 to 31 == 64 to 95 - * 128 to 138 == 96 to 106 - * - * Table B - * ASCII CODE128 - * 32 to 138 == 0 to 106 - * - * Table C - * ASCII CODE128 - * "00" to "99" == 0 to 99 - * 132 to 138 == 100 to 106 - * - * @param string $value - * @param string $set - * @return int - */ - protected function ord128($value, $set) - { - $ord = ord($value); - if ($set === 'A') { - if ($ord < 32) { - return $ord + 64; - } elseif ($ord < 96) { - return $ord - 32; - } elseif ($ord > 138) { - return -1; - } else { - return $ord - 32; - } - } elseif ($set === 'B') { - if ($ord < 32) { - return -1; - } elseif ($ord <= 138) { - return $ord - 32; - } else { - return -1; - } - } elseif ($set === 'C') { - $val = (int) $value; - if (($val >= 0) && ($val <= 99)) { - return $val; - } elseif (($ord >= 132) && ($ord <= 138)) { - return $ord - 32; - } else { - return -1; - } - } else { - if ($ord < 32) { - return $ord + 64; - } elseif ($ord <= 138) { - return $ord - 32; - } else { - return -1; - } - } - } - - /** - * Internal Method to return the ascii value from a code128 integer - * - * Table A - * ASCII CODE128 - * 32 to 95 == 0 to 63 - * 0 to 31 == 64 to 95 - * 128 to 138 == 96 to 106 - * - * Table B - * ASCII CODE128 - * 32 to 138 == 0 to 106 - * - * Table C - * ASCII CODE128 - * "00" to "99" == 0 to 99 - * 132 to 138 == 100 to 106 - * - * @param int $value - * @param string $set - * @return int|string - */ - protected function chr128($value, $set) - { - if ($set === 'A') { - if ($value < 64) { - return chr($value + 32); - } elseif ($value < 96) { - return chr($value - 64); - } elseif ($value > 106) { - return -1; - } else { - return chr($value + 32); - } - } elseif ($set === 'B') { - if ($value > 106) { - return -1; - } else { - return chr($value + 32); - } - } elseif ($set === 'C') { - if (($value >= 0) && ($value <= 9)) { - return '0' . (string) $value; - } elseif ($value <= 99) { - return (string) $value; - } elseif ($value <= 106) { - return chr($value + 32); - } else { - return -1; - } - } else { - if ($value <= 106) { - return $value + 32; - } else { - return -1; - } - } - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Code25.php b/lib/laminas/laminas-validator/src/Barcode/Code25.php deleted file mode 100644 index 7134eb7cd..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Code25.php +++ /dev/null @@ -1,17 +0,0 @@ -setLength(-1); - $this->setCharacters('0123456789'); - $this->setChecksum('code25'); - $this->useChecksum(false); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Code25interleaved.php b/lib/laminas/laminas-validator/src/Barcode/Code25interleaved.php deleted file mode 100644 index cce21b20e..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Code25interleaved.php +++ /dev/null @@ -1,19 +0,0 @@ -setLength('even'); - $this->setCharacters('0123456789'); - $this->setChecksum('code25'); - $this->useChecksum(false); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Code39.php b/lib/laminas/laminas-validator/src/Barcode/Code39.php deleted file mode 100644 index 4b101191c..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Code39.php +++ /dev/null @@ -1,90 +0,0 @@ - 0, - '1' => 1, - '2' => 2, - '3' => 3, - '4' => 4, - '5' => 5, - '6' => 6, - '7' => 7, - '8' => 8, - '9' => 9, - 'A' => 10, - 'B' => 11, - 'C' => 12, - 'D' => 13, - 'E' => 14, - 'F' => 15, - 'G' => 16, - 'H' => 17, - 'I' => 18, - 'J' => 19, - 'K' => 20, - 'L' => 21, - 'M' => 22, - 'N' => 23, - 'O' => 24, - 'P' => 25, - 'Q' => 26, - 'R' => 27, - 'S' => 28, - 'T' => 29, - 'U' => 30, - 'V' => 31, - 'W' => 32, - 'X' => 33, - 'Y' => 34, - 'Z' => 35, - '-' => 36, - '.' => 37, - ' ' => 38, - '$' => 39, - '/' => 40, - '+' => 41, - '%' => 42, - ]; - - /** - * Constructor for this barcode adapter - */ - public function __construct() - { - $this->setLength(-1); - $this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -.$/+%'); - $this->setChecksum('code39'); - $this->useChecksum(false); - } - - /** - * Validates the checksum (Modulo 43) - * - * @param string $value The barcode to validate - * @return bool - */ - protected function code39($value) - { - $checksum = substr($value, -1, 1); - $value = str_split(substr($value, 0, -1)); - $count = 0; - foreach ($value as $char) { - $count += $this->check[$char]; - } - - $mod = $count % 43; - if ($mod === $this->check[$checksum]) { - return true; - } - - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Code39ext.php b/lib/laminas/laminas-validator/src/Barcode/Code39ext.php deleted file mode 100644 index d23123c0a..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Code39ext.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(-1); - $this->setCharacters(128); - $this->useChecksum(false); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Code93.php b/lib/laminas/laminas-validator/src/Barcode/Code93.php deleted file mode 100644 index 92905ec17..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Code93.php +++ /dev/null @@ -1,119 +0,0 @@ - 0, - '1' => 1, - '2' => 2, - '3' => 3, - '4' => 4, - '5' => 5, - '6' => 6, - '7' => 7, - '8' => 8, - '9' => 9, - 'A' => 10, - 'B' => 11, - 'C' => 12, - 'D' => 13, - 'E' => 14, - 'F' => 15, - 'G' => 16, - 'H' => 17, - 'I' => 18, - 'J' => 19, - 'K' => 20, - 'L' => 21, - 'M' => 22, - 'N' => 23, - 'O' => 24, - 'P' => 25, - 'Q' => 26, - 'R' => 27, - 'S' => 28, - 'T' => 29, - 'U' => 30, - 'V' => 31, - 'W' => 32, - 'X' => 33, - 'Y' => 34, - 'Z' => 35, - '-' => 36, - '.' => 37, - ' ' => 38, - '$' => 39, - '/' => 40, - '+' => 41, - '%' => 42, - '!' => 43, - '"' => 44, - '§' => 45, - '&' => 46, - ]; - - /** - * Constructor for this barcode adapter - */ - public function __construct() - { - $this->setLength(-1); - $this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ -.$/+%'); - $this->setChecksum('code93'); - $this->useChecksum(false); - } - - /** - * Validates the checksum (Modulo CK) - * - * @param string $value The barcode to validate - * @return bool - */ - protected function code93($value) - { - $checksum = substr($value, -2, 2); - $value = str_split(substr($value, 0, -2)); - $count = 0; - $length = count($value) % 20; - foreach ($value as $char) { - if ($length === 0) { - $length = 20; - } - - $count += $this->check[$char] * $length; - --$length; - } - - $check = array_search($count % 47, $this->check); - $value[] = $check; - $count = 0; - $length = count($value) % 15; - foreach ($value as $char) { - if ($length === 0) { - $length = 15; - } - - $count += $this->check[$char] * $length; - --$length; - } - $check .= array_search($count % 47, $this->check); - - if ($check === $checksum) { - return true; - } - - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Code93ext.php b/lib/laminas/laminas-validator/src/Barcode/Code93ext.php deleted file mode 100644 index 216d72285..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Code93ext.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(-1); - $this->setCharacters(128); - $this->useChecksum(false); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Ean12.php b/lib/laminas/laminas-validator/src/Barcode/Ean12.php deleted file mode 100644 index 82be6c5a5..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Ean12.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(12); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Ean13.php b/lib/laminas/laminas-validator/src/Barcode/Ean13.php deleted file mode 100644 index 261a687fd..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Ean13.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(13); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Ean14.php b/lib/laminas/laminas-validator/src/Barcode/Ean14.php deleted file mode 100644 index 9be798b08..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Ean14.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(14); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Ean18.php b/lib/laminas/laminas-validator/src/Barcode/Ean18.php deleted file mode 100644 index f2c32204e..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Ean18.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(18); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Ean2.php b/lib/laminas/laminas-validator/src/Barcode/Ean2.php deleted file mode 100644 index a49ea9b9a..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Ean2.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(2); - $this->setCharacters('0123456789'); - $this->useChecksum(false); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Ean5.php b/lib/laminas/laminas-validator/src/Barcode/Ean5.php deleted file mode 100644 index 0433c80a2..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Ean5.php +++ /dev/null @@ -1,18 +0,0 @@ -setLength(5); - $this->setCharacters('0123456789'); - $this->useChecksum(false); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Ean8.php b/lib/laminas/laminas-validator/src/Barcode/Ean8.php deleted file mode 100644 index 7f1399a46..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Ean8.php +++ /dev/null @@ -1,35 +0,0 @@ -setLength([7, 8]); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } - - /** - * Overrides parent checkLength - * - * @param string $value Value - * @return bool - */ - public function hasValidLength($value) - { - if (strlen($value) === 7) { - $this->useChecksum(false); - } else { - $this->useChecksum(true); - } - - return parent::hasValidLength($value); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Gtin12.php b/lib/laminas/laminas-validator/src/Barcode/Gtin12.php deleted file mode 100644 index f667d1f50..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Gtin12.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(12); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Gtin13.php b/lib/laminas/laminas-validator/src/Barcode/Gtin13.php deleted file mode 100644 index 4f02651ec..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Gtin13.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(13); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Gtin14.php b/lib/laminas/laminas-validator/src/Barcode/Gtin14.php deleted file mode 100644 index 2ec6624ce..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Gtin14.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(14); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Identcode.php b/lib/laminas/laminas-validator/src/Barcode/Identcode.php deleted file mode 100644 index a0c4cf63a..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Identcode.php +++ /dev/null @@ -1,37 +0,0 @@ -setLength(12); - $this->setCharacters('0123456789'); - $this->setChecksum('identcode'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Intelligentmail.php b/lib/laminas/laminas-validator/src/Barcode/Intelligentmail.php deleted file mode 100644 index d34569f1b..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Intelligentmail.php +++ /dev/null @@ -1,18 +0,0 @@ -setLength([20, 25, 29, 31]); - $this->setCharacters('0123456789'); - $this->useChecksum(false); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Issn.php b/lib/laminas/laminas-validator/src/Barcode/Issn.php deleted file mode 100644 index e99321244..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Issn.php +++ /dev/null @@ -1,91 +0,0 @@ -setLength([8, 13]); - $this->setCharacters('0123456789X'); - $this->setChecksum('gtin'); - } - - /** - * Allows X on length of 8 chars - * - * @param string $value The barcode to check for allowed characters - * @return bool - */ - public function hasValidCharacters($value) - { - if (strlen($value) !== 8) { - if (str_contains($value, 'X')) { - return false; - } - } - - return parent::hasValidCharacters($value); - } - - /** - * Validates the checksum - * - * @param string $value The barcode to check the checksum for - * @return bool - */ - public function hasValidChecksum($value) - { - if (strlen($value) === 8) { - $this->setChecksum('issn'); - } else { - $this->setChecksum('gtin'); - } - - return parent::hasValidChecksum($value); - } - - /** - * Validates the checksum () - * ISSN implementation (reversed mod11) - * - * @param string $value The barcode to validate - * @return bool - */ - protected function issn($value) - { - $checksum = substr($value, -1, 1); - $values = str_split(substr($value, 0, -1)); - $check = 0; - $multi = 8; - foreach ($values as $token) { - if ($token === 'X') { - $token = 10; - } - - $check += $token * $multi; - --$multi; - } - - $check %= 11; - $check = $check === 0 ? 0 : 11 - $check; - - if ((string) $check === $checksum) { - return true; - } - - if (($check === 10) && ($checksum === 'X')) { - return true; - } - - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Itf14.php b/lib/laminas/laminas-validator/src/Barcode/Itf14.php deleted file mode 100644 index c8683ff19..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Itf14.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(14); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Leitcode.php b/lib/laminas/laminas-validator/src/Barcode/Leitcode.php deleted file mode 100644 index c4a0dc107..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Leitcode.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(14); - $this->setCharacters('0123456789'); - $this->setChecksum('identcode'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Planet.php b/lib/laminas/laminas-validator/src/Barcode/Planet.php deleted file mode 100644 index e966065b9..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Planet.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength([12, 14]); - $this->setCharacters('0123456789'); - $this->setChecksum('postnet'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Postnet.php b/lib/laminas/laminas-validator/src/Barcode/Postnet.php deleted file mode 100644 index f3261e138..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Postnet.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength([6, 7, 10, 12]); - $this->setCharacters('0123456789'); - $this->setChecksum('postnet'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Royalmail.php b/lib/laminas/laminas-validator/src/Barcode/Royalmail.php deleted file mode 100644 index 9c3d306ef..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Royalmail.php +++ /dev/null @@ -1,156 +0,0 @@ - */ - protected $rows = [ - '0' => 1, - '1' => 1, - '2' => 1, - '3' => 1, - '4' => 1, - '5' => 1, - '6' => 2, - '7' => 2, - '8' => 2, - '9' => 2, - 'A' => 2, - 'B' => 2, - 'C' => 3, - 'D' => 3, - 'E' => 3, - 'F' => 3, - 'G' => 3, - 'H' => 3, - 'I' => 4, - 'J' => 4, - 'K' => 4, - 'L' => 4, - 'M' => 4, - 'N' => 4, - 'O' => 5, - 'P' => 5, - 'Q' => 5, - 'R' => 5, - 'S' => 5, - 'T' => 5, - 'U' => 0, - 'V' => 0, - 'W' => 0, - 'X' => 0, - 'Y' => 0, - 'Z' => 0, - ]; - - /** @var array */ - protected $columns = [ - '0' => 1, - '1' => 2, - '2' => 3, - '3' => 4, - '4' => 5, - '5' => 0, - '6' => 1, - '7' => 2, - '8' => 3, - '9' => 4, - 'A' => 5, - 'B' => 0, - 'C' => 1, - 'D' => 2, - 'E' => 3, - 'F' => 4, - 'G' => 5, - 'H' => 0, - 'I' => 1, - 'J' => 2, - 'K' => 3, - 'L' => 4, - 'M' => 5, - 'N' => 0, - 'O' => 1, - 'P' => 2, - 'Q' => 3, - 'R' => 4, - 'S' => 5, - 'T' => 0, - 'U' => 1, - 'V' => 2, - 'W' => 3, - 'X' => 4, - 'Y' => 5, - 'Z' => 0, - ]; - - /** - * Constructor for this barcode adapter - */ - public function __construct() - { - $this->setLength(-1); - $this->setCharacters('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'); - $this->setChecksum('royalmail'); - } - - /** - * Validates the checksum () - * - * @param string $value The barcode to validate - * @return bool - */ - protected function royalmail($value) - { - $checksum = substr($value, -1, 1); - $values = str_split(substr($value, 0, -1)); - $rowvalue = 0; - $colvalue = 0; - foreach ($values as $row) { - $rowvalue += $this->rows[$row]; - $colvalue += $this->columns[$row]; - } - - $rowvalue %= 6; - $colvalue %= 6; - - $rowchkvalue = array_keys($this->rows, $rowvalue); - $colchkvalue = array_keys($this->columns, $colvalue); - $intersect = array_intersect($rowchkvalue, $colchkvalue); - $chkvalue = (string) current($intersect); - - if ($chkvalue === $checksum) { - return true; - } - - return false; - } - - /** - * Allows start and stop tag within checked chars - * - * @param string $value The barcode to check for allowed characters - * @return bool - */ - public function hasValidCharacters($value) - { - if ($value[0] === '(') { - $value = substr($value, 1); - - if ($value[strlen($value) - 1] === ')') { - $value = substr($value, 0, -1); - } else { - return false; - } - } - - return parent::hasValidCharacters($value); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Sscc.php b/lib/laminas/laminas-validator/src/Barcode/Sscc.php deleted file mode 100644 index 44f804233..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Sscc.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(18); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Upca.php b/lib/laminas/laminas-validator/src/Barcode/Upca.php deleted file mode 100644 index d5d804177..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Upca.php +++ /dev/null @@ -1,16 +0,0 @@ -setLength(12); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } -} diff --git a/lib/laminas/laminas-validator/src/Barcode/Upce.php b/lib/laminas/laminas-validator/src/Barcode/Upce.php deleted file mode 100644 index 3532b42c6..000000000 --- a/lib/laminas/laminas-validator/src/Barcode/Upce.php +++ /dev/null @@ -1,35 +0,0 @@ -setLength([6, 7, 8]); - $this->setCharacters('0123456789'); - $this->setChecksum('gtin'); - } - - /** - * Overrides parent checkLength - * - * @param string $value Value - * @return bool - */ - public function hasValidLength($value) - { - if (strlen($value) !== 8) { - $this->useChecksum(false); - } else { - $this->useChecksum(true); - } - - return parent::hasValidLength($value); - } -} diff --git a/lib/laminas/laminas-validator/src/Between.php b/lib/laminas/laminas-validator/src/Between.php deleted file mode 100644 index 40d474ebd..000000000 --- a/lib/laminas/laminas-validator/src/Between.php +++ /dev/null @@ -1,215 +0,0 @@ - - */ - protected $messageTemplates = [ - self::NOT_BETWEEN => "The input is not between '%min%' and '%max%', inclusively", - self::NOT_BETWEEN_STRICT => "The input is not strictly between '%min%' and '%max%'", - self::VALUE_NOT_NUMERIC => "The min ('%min%') and max ('%max%') values are numeric, but the input is not", - self::VALUE_NOT_STRING => "The min ('%min%') and max ('%max%') values are non-numeric strings, " - . 'but the input is not a string', - ]; - - /** - * Additional variables available for validation failure messages - * - * @var array - */ - protected $messageVariables = [ - 'min' => ['options' => 'min'], - 'max' => ['options' => 'max'], - ]; - - /** - * Options for the between validator - * - * @var array - */ - protected $options = [ - 'inclusive' => true, // Whether to do inclusive comparisons, allowing equivalence to min and/or max - 'min' => 0, - 'max' => PHP_INT_MAX, - ]; - - /** - * Sets validator options - * Accepts the following option keys: - * 'min' => scalar, minimum border - * 'max' => scalar, maximum border - * 'inclusive' => boolean, inclusive border values - * - * @param array|Traversable $options - * @throws Exception\InvalidArgumentException - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - if (! is_array($options)) { - $temp = []; - /** @psalm-var array $options */ - $options = func_get_args(); - $temp['min'] = array_shift($options); - if (! empty($options)) { - $temp['max'] = array_shift($options); - } - - if (! empty($options)) { - $temp['inclusive'] = array_shift($options); - } - - $options = $temp; - } - - if (! array_key_exists('min', $options) || ! array_key_exists('max', $options)) { - throw new Exception\InvalidArgumentException("Missing option: 'min' and 'max' have to be given"); - } - - if ( - (isset($options['min']) && is_numeric($options['min'])) - && (isset($options['max']) && is_numeric($options['max'])) - ) { - $this->numeric = true; - } elseif ( - (isset($options['min']) && is_string($options['min'])) - && (isset($options['max']) && is_string($options['max'])) - ) { - $this->numeric = false; - } else { - throw new Exception\InvalidArgumentException( - "Invalid options: 'min' and 'max' should be of the same scalar type" - ); - } - - parent::__construct($options); - } - - /** - * Returns the min option - * - * @return mixed - */ - public function getMin() - { - return $this->options['min']; - } - - /** - * Sets the min option - * - * @return $this Provides a fluent interface - */ - public function setMin(mixed $min) - { - $this->options['min'] = $min; - return $this; - } - - /** - * Returns the max option - * - * @return mixed - */ - public function getMax() - { - return $this->options['max']; - } - - /** - * Sets the max option - * - * @return $this Provides a fluent interface - */ - public function setMax(mixed $max) - { - $this->options['max'] = $max; - return $this; - } - - /** - * Returns the inclusive option - * - * @return bool - */ - public function getInclusive() - { - return $this->options['inclusive']; - } - - /** - * Sets the inclusive option - * - * @param bool $inclusive - * @return $this Provides a fluent interface - */ - public function setInclusive($inclusive) - { - $this->options['inclusive'] = $inclusive; - return $this; - } - - /** - * Returns true if and only if $value is between min and max options, inclusively - * if inclusive option is true. - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - $this->setValue($value); - - if ($this->numeric && ! is_numeric($value)) { - $this->error(self::VALUE_NOT_NUMERIC); - return false; - } - if (! $this->numeric && ! is_string($value)) { - $this->error(self::VALUE_NOT_STRING); - return false; - } - - if ($this->getInclusive()) { - if ($this->getMin() > $value || $value > $this->getMax()) { - $this->error(self::NOT_BETWEEN); - return false; - } - } else { - if ($this->getMin() >= $value || $value >= $this->getMax()) { - $this->error(self::NOT_BETWEEN_STRICT); - return false; - } - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Bitwise.php b/lib/laminas/laminas-validator/src/Bitwise.php deleted file mode 100644 index d718a020f..000000000 --- a/lib/laminas/laminas-validator/src/Bitwise.php +++ /dev/null @@ -1,203 +0,0 @@ - - */ - protected $messageTemplates = [ - self::NOT_AND => "The input has no common bit set with '%control%'", - self::NOT_AND_STRICT => "The input doesn't have the same bits set as '%control%'", - self::NOT_XOR => "The input has common bit set with '%control%'", - self::NO_OP => "No operator was present to compare '%control%' against", - ]; - - /** - * Additional variables available for validation failure messages - * - * @var array - */ - protected $messageVariables = [ - 'control' => 'control', - ]; - - /** @var null|int */ - protected $operator; - - /** @var bool */ - protected $strict = false; - - /** - * Sets validator options - * Accepts the following option keys: - * 'control' => int - * 'operator' => - * 'strict' => bool - * - * @param array|Traversable $options - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = iterator_to_array($options); - } - - if (! is_array($options)) { - $options = func_get_args(); - - $temp['control'] = array_shift($options); - - if (! empty($options)) { - $temp['operator'] = array_shift($options); - } - - if (! empty($options)) { - $temp['strict'] = array_shift($options); - } - - $options = $temp; - } - - parent::__construct($options); - } - - /** - * Returns the control parameter. - * - * @return integer - */ - public function getControl() - { - return $this->control; - } - - /** - * Returns the operator parameter. - * - * @return null|int - */ - public function getOperator() - { - return $this->operator; - } - - /** - * Returns the strict parameter. - * - * @return boolean - */ - public function getStrict() - { - return $this->strict; - } - - /** - * Returns true if and only if $value is between min and max options, inclusively - * if inclusive option is true. - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - $this->setValue($value); - - if (self::OP_AND === $this->operator) { - if ($this->strict) { - // All the bits set in value must be set in control - $result = ($this->control & $value) === $value; - - if (! $result) { - $this->error(self::NOT_AND_STRICT); - } - - return $result; - } - - // At least one of the bits must be common between value and control - $result = (bool) ($this->control & $value); - - if (! $result) { - $this->error(self::NOT_AND); - } - - return $result; - } - - if (self::OP_XOR === $this->operator) { - // Parentheses are required due to order of operations with bitwise operations - // phpcs:ignore WebimpressCodingStandard.Formatting.RedundantParentheses.SingleEquality - $result = ($this->control ^ $value) === ($this->control | $value); - - if (! $result) { - $this->error(self::NOT_XOR); - } - - return $result; - } - - $this->error(self::NO_OP); - return false; - } - - /** - * Sets the control parameter. - * - * @param integer $control - * @return $this - */ - public function setControl($control) - { - $this->control = (int) $control; - - return $this; - } - - /** - * Sets the operator parameter. - * - * @param string $operator - * @return $this - */ - public function setOperator($operator) - { - $this->operator = $operator; - - return $this; - } - - /** - * Sets the strict parameter. - * - * @param boolean $strict - * @return $this - */ - public function setStrict($strict) - { - $this->strict = (bool) $strict; - - return $this; - } -} diff --git a/lib/laminas/laminas-validator/src/BusinessIdentifierCode.php b/lib/laminas/laminas-validator/src/BusinessIdentifierCode.php deleted file mode 100644 index 4f42578f5..000000000 --- a/lib/laminas/laminas-validator/src/BusinessIdentifierCode.php +++ /dev/null @@ -1,327 +0,0 @@ - 'Invalid type given; string expected', - self::INVALID => 'Invalid BIC format', - self::NOT_VALID_COUNTRY => 'Invalid country code', - ]; - - /** - * @see https://www.bundesbank.de/resource/blob/749660/d2c6e00664251b4d83483c229e084e44/mL/technische-spezifikationen-scc-anhang-112018-data.pdf (page 39) - */ - private const REGEX_BIC = '/^[a-z]{4}(?[a-z]{2})[a-z2-9][a-np-z0-9]([0-9a-z]{3})?$/i'; - - /** - * List of all country codes defined by ISO 3166-1 alpha-2 - * - * @see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Current_codes - * - * @var string[] - */ - private const ISO_COUNTRIES = [ - 'AD', - 'AE', - 'AF', - 'AG', - 'AI', - 'AL', - 'AM', - 'AO', - 'AQ', - 'AR', - 'AS', - 'AT', - 'AU', - 'AW', - 'AX', - 'AZ', - 'BA', - 'BB', - 'BD', - 'BE', - 'BF', - 'BG', - 'BH', - 'BI', - 'BJ', - 'BL', - 'BM', - 'BN', - 'BO', - 'BQ', - 'BQ', - 'BR', - 'BS', - 'BT', - 'BV', - 'BW', - 'BY', - 'BZ', - 'CA', - 'CC', - 'CD', - 'CF', - 'CG', - 'CH', - 'CI', - 'CK', - 'CL', - 'CM', - 'CN', - 'CO', - 'CR', - 'CU', - 'CV', - 'CW', - 'CX', - 'CY', - 'CZ', - 'DE', - 'DJ', - 'DK', - 'DM', - 'DO', - 'DZ', - 'EC', - 'EE', - 'EG', - 'EH', - 'ER', - 'ES', - 'ET', - 'FI', - 'FJ', - 'FK', - 'FM', - 'FO', - 'FR', - 'GA', - 'GB', - 'GD', - 'GE', - 'GF', - 'GG', - 'GH', - 'GI', - 'GL', - 'GM', - 'GN', - 'GP', - 'GQ', - 'GR', - 'GS', - 'GT', - 'GU', - 'GW', - 'GY', - 'HK', - 'HM', - 'HN', - 'HR', - 'HT', - 'HU', - 'ID', - 'IE', - 'IL', - 'IM', - 'IN', - 'IO', - 'IQ', - 'IR', - 'IS', - 'IT', - 'JE', - 'JM', - 'JO', - 'JP', - 'KE', - 'KG', - 'KH', - 'KI', - 'KM', - 'KN', - 'KP', - 'KR', - 'KW', - 'KY', - 'KZ', - 'LA', - 'LB', - 'LC', - 'LI', - 'LK', - 'LR', - 'LS', - 'LT', - 'LU', - 'LV', - 'LY', - 'MA', - 'MC', - 'MD', - 'ME', - 'MF', - 'MG', - 'MH', - 'MK', - 'ML', - 'MM', - 'MN', - 'MO', - 'MP', - 'MQ', - 'MR', - 'MS', - 'MT', - 'MU', - 'MV', - 'MW', - 'MX', - 'MY', - 'MZ', - 'NA', - 'NC', - 'NE', - 'NF', - 'NG', - 'NI', - 'NL', - 'NO', - 'NP', - 'NR', - 'NU', - 'NZ', - 'OM', - 'PA', - 'PE', - 'PF', - 'PG', - 'PH', - 'PK', - 'PL', - 'PM', - 'PN', - 'PR', - 'PS', - 'PT', - 'PW', - 'PY', - 'QA', - 'RE', - 'RO', - 'RS', - 'RU', - 'RW', - 'SA', - 'SB', - 'SC', - 'SD', - 'SE', - 'SG', - 'SH', - 'SI', - 'SJ', - 'SK', - 'SL', - 'SM', - 'SN', - 'SO', - 'SR', - 'SS', - 'ST', - 'SV', - 'SX', - 'SY', - 'SZ', - 'TC', - 'TD', - 'TF', - 'TG', - 'TH', - 'TJ', - 'TK', - 'TL', - 'TM', - 'TN', - 'TO', - 'TR', - 'TT', - 'TV', - 'TW', - 'TZ', - 'UA', - 'UG', - 'UM', - 'US', - 'UY', - 'UZ', - 'VA', - 'VC', - 'VE', - 'VG', - 'VI', - 'VN', - 'VU', - 'WF', - 'WS', - 'YE', - 'YT', - 'ZA', - 'ZM', - 'ZW', - ]; - - /** - * This code is the only one used by SWIFT that is not defined by ISO 3166-1 alpha-2 - * - * @see https://en.wikipedia.org/wiki/ISO_9362 - * - * @var string - */ - private const KOSOVO_EXCEPTION = 'XK'; - - /** {@inheritDoc} */ - public function isValid($value): bool - { - if (! is_string($value)) { - $this->error(self::NOT_STRING); - return false; - } - - if ( - empty($value) - || ! preg_match(self::REGEX_BIC, $value, $matches) - ) { - $this->error(self::INVALID); - return false; - } - - if (! $this->isSwiftValidCountry($matches['country'])) { - $this->error(self::NOT_VALID_COUNTRY); - return false; - } - - return true; - } - - private function isSwiftValidCountry(string $countryCode): bool - { - $countryCode = strtoupper($countryCode); - return in_array($countryCode, self::ISO_COUNTRIES, true) - || $countryCode === self::KOSOVO_EXCEPTION; - } -} diff --git a/lib/laminas/laminas-validator/src/Callback.php b/lib/laminas/laminas-validator/src/Callback.php deleted file mode 100644 index fc3fb9652..000000000 --- a/lib/laminas/laminas-validator/src/Callback.php +++ /dev/null @@ -1,149 +0,0 @@ - 'The input is not valid', - self::INVALID_CALLBACK => 'An exception has been raised within the callback', - ]; - - /** - * Default options to set for the validator - * - * @var mixed - */ - protected $options = [ - 'callback' => null, // Callback in a call_user_func format, string || array - 'callbackOptions' => [], // Options for the callback - ]; - - /** - * Constructor - * - * @param array|callable $options - */ - public function __construct($options = null) - { - if (is_callable($options)) { - $options = ['callback' => $options]; - } - - parent::__construct($options); - } - - /** - * Returns the set callback - * - * @return mixed - */ - public function getCallback() - { - return $this->options['callback']; - } - - /** - * Sets the callback - * - * @param string|array|callable $callback - * @return $this Provides a fluent interface - * @throws InvalidArgumentException - */ - public function setCallback($callback) - { - if (! is_callable($callback)) { - throw new InvalidArgumentException('Invalid callback given'); - } - - $this->options['callback'] = $callback; - return $this; - } - - /** - * Returns the set options for the callback - * - * @return mixed - */ - public function getCallbackOptions() - { - return $this->options['callbackOptions']; - } - - /** - * Sets options for the callback - * - * @return $this Provides a fluent interface - */ - public function setCallbackOptions(mixed $options) - { - $this->options['callbackOptions'] = (array) $options; - return $this; - } - - /** - * Returns true if and only if the set callback returns - * for the provided $value - * - * @param mixed $value - * @param mixed $context Additional context to provide to the callback - * @return bool - * @throws InvalidArgumentException - */ - public function isValid($value, $context = null) - { - $this->setValue($value); - - $options = $this->getCallbackOptions(); - $callback = $this->getCallback(); - if (empty($callback)) { - throw new InvalidArgumentException('No callback given'); - } - - $args = [$value]; - if (empty($options) && ! empty($context)) { - $args[] = $context; - } - if (! empty($options) && empty($context)) { - $args = array_merge($args, $options); - } - if (! empty($options) && ! empty($context)) { - $args[] = $context; - $args = array_merge($args, $options); - } - - try { - if (! call_user_func_array($callback, $args)) { - $this->error(self::INVALID_VALUE); - return false; - } - } catch (Exception) { - $this->error(self::INVALID_CALLBACK); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/ConfigProvider.php b/lib/laminas/laminas-validator/src/ConfigProvider.php deleted file mode 100644 index 188ebc39d..000000000 --- a/lib/laminas/laminas-validator/src/ConfigProvider.php +++ /dev/null @@ -1,38 +0,0 @@ - $this->getDependencyConfig(), - ]; - } - - /** - * Return dependency mappings for this component. - * - * @return array - */ - public function getDependencyConfig() - { - return [ - 'aliases' => [ - 'ValidatorManager' => ValidatorPluginManager::class, - - // Legacy Zend Framework aliases - 'Zend\Validator\ValidatorPluginManager' => ValidatorPluginManager::class, - ], - 'factories' => [ - ValidatorPluginManager::class => ValidatorPluginManagerFactory::class, - ], - ]; - } -} diff --git a/lib/laminas/laminas-validator/src/CreditCard.php b/lib/laminas/laminas-validator/src/CreditCard.php deleted file mode 100644 index baa385bfc..000000000 --- a/lib/laminas/laminas-validator/src/CreditCard.php +++ /dev/null @@ -1,436 +0,0 @@ - 'The input seems to contain an invalid checksum', - self::CONTENT => 'The input must contain only digits', - self::INVALID => 'Invalid type given. String expected', - self::LENGTH => 'The input contains an invalid amount of digits', - self::PREFIX => 'The input is not from an allowed institute', - self::SERVICE => 'The input seems to be an invalid credit card number', - self::SERVICEFAILURE => 'An exception has been raised while validating the input', - ]; - - /** - * List of CCV names - * - * @var array - */ - protected $cardName = [ - 0 => self::AMERICAN_EXPRESS, - 1 => self::DINERS_CLUB, - 2 => self::DINERS_CLUB_US, - 3 => self::DISCOVER, - 4 => self::JCB, - 5 => self::LASER, - 6 => self::MAESTRO, - 7 => self::MASTERCARD, - 8 => self::SOLO, - 9 => self::UNIONPAY, - 10 => self::VISA, - 11 => self::MIR, - ]; - - /** - * List of allowed CCV lengths - * - * @var array - */ - protected $cardLength = [ - self::AMERICAN_EXPRESS => [15], - self::DINERS_CLUB => [14], - self::DINERS_CLUB_US => [16], - self::DISCOVER => [16, 19], - self::JCB => [15, 16], - self::LASER => [16, 17, 18, 19], - self::MAESTRO => [12, 13, 14, 15, 16, 17, 18, 19], - self::MASTERCARD => [16], - self::SOLO => [16, 18, 19], - self::UNIONPAY => [16, 17, 18, 19], - self::VISA => [13, 16, 19], - self::MIR => [13, 16], - ]; - - /** - * List of accepted CCV provider tags - * - * @var array - */ - protected $cardType = [ - self::AMERICAN_EXPRESS => ['34', '37'], - self::DINERS_CLUB => ['300', '301', '302', '303', '304', '305', '36'], - self::DINERS_CLUB_US => ['54', '55'], - self::DISCOVER => [ - '6011', - '622126', - '622127', - '622128', - '622129', - '62213', - '62214', - '62215', - '62216', - '62217', - '62218', - '62219', - '6222', - '6223', - '6224', - '6225', - '6226', - '6227', - '6228', - '62290', - '62291', - '622920', - '622921', - '622922', - '622923', - '622924', - '622925', - '644', - '645', - '646', - '647', - '648', - '649', - '65', - ], - self::JCB => ['1800', '2131', '3528', '3529', '353', '354', '355', '356', '357', '358'], - self::LASER => ['6304', '6706', '6771', '6709'], - self::MAESTRO => [ - '5018', - '5020', - '5038', - '6304', - '6759', - '6761', - '6762', - '6763', - '6764', - '6765', - '6766', - '6772', - ], - self::MASTERCARD => [ - '2221', - '2222', - '2223', - '2224', - '2225', - '2226', - '2227', - '2228', - '2229', - '223', - '224', - '225', - '226', - '227', - '228', - '229', - '23', - '24', - '25', - '26', - '271', - '2720', - '51', - '52', - '53', - '54', - '55', - ], - self::SOLO => ['6334', '6767'], - self::UNIONPAY => [ - '622126', - '622127', - '622128', - '622129', - '62213', - '62214', - '62215', - '62216', - '62217', - '62218', - '62219', - '6222', - '6223', - '6224', - '6225', - '6226', - '6227', - '6228', - '62290', - '62291', - '622920', - '622921', - '622922', - '622923', - '622924', - '622925', - ], - self::VISA => ['4'], - self::MIR => ['2200', '2201', '2202', '2203', '2204'], - ]; - - /** - * Options for this validator - * - * @var array - */ - protected $options = [ - 'service' => null, // Service callback for additional validation - 'type' => [], // CCIs which are accepted by validation - ]; - - /** - * Constructor - * - * @param string|array|Traversable $options OPTIONAL Type of CCI to allow - */ - public function __construct($options = []) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } elseif (! is_array($options)) { - $options = func_get_args(); - $temp['type'] = array_shift($options); - if (! empty($options)) { - $temp['service'] = array_shift($options); - } - - $options = $temp; - } - - if (! array_key_exists('type', $options)) { - $options['type'] = self::ALL; - } - - $this->setType($options['type']); - unset($options['type']); - - if (array_key_exists('service', $options)) { - $this->setService($options['service']); - unset($options['service']); - } - - parent::__construct($options); - } - - /** - * Returns a list of accepted CCIs - * - * @return array - */ - public function getType() - { - return $this->options['type']; - } - - /** - * Sets CCIs which are accepted by validation - * - * @param string|array $type Type to allow for validation - * @return CreditCard Provides a fluid interface - */ - public function setType($type) - { - $this->options['type'] = []; - return $this->addType($type); - } - - /** - * Adds a CCI to be accepted by validation - * - * @param string|array $type Type to allow for validation - * @return $this Provides a fluid interface - */ - public function addType($type) - { - if (is_string($type)) { - $type = [$type]; - } - - foreach ($type as $typ) { - if ($typ === self::ALL) { - $this->options['type'] = array_keys($this->cardLength); - continue; - } - - if (in_array($typ, $this->options['type'])) { - continue; - } - - $constant = 'static::' . strtoupper($typ); - if (! defined($constant) || in_array(constant($constant), $this->options['type'])) { - continue; - } - $this->options['type'][] = constant($constant); - } - - return $this; - } - - /** - * Returns the actual set service - * - * @return callable - */ - public function getService() - { - return $this->options['service']; - } - - /** - * Sets a new callback for service validation - * - * @param callable $service - * @return $this - * @throws InvalidArgumentException On invalid service callback. - */ - public function setService($service) - { - if (! is_callable($service)) { - throw new InvalidArgumentException('Invalid callback given'); - } - - $this->options['service'] = $service; - return $this; - } - - /** - * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum) - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - $this->setValue($value); - - if (! is_string($value)) { - $this->error(self::INVALID, $value); - return false; - } - - if (! ctype_digit($value)) { - $this->error(self::CONTENT, $value); - return false; - } - - $length = strlen($value); - $types = $this->getType(); - $foundp = false; - $foundl = false; - foreach ($types as $type) { - foreach ($this->cardType[$type] as $prefix) { - if (str_starts_with($value, (string) $prefix)) { - $foundp = true; - if (in_array($length, $this->cardLength[$type])) { - $foundl = true; - break 2; - } - } - } - } - - if ($foundp === false) { - $this->error(self::PREFIX, $value); - return false; - } - - if ($foundl === false) { - $this->error(self::LENGTH, $value); - return false; - } - - $sum = 0; - $weight = 2; - - for ($i = $length - 2; $i >= 0; $i--) { - $digit = $weight * $value[$i]; - $sum += floor($digit / 10) + $digit % 10; - $weight = $weight % 2 + 1; - } - - $checksum = (10 - $sum % 10) % 10; - if ((string) $checksum !== $value[$length - 1]) { - $this->error(self::CHECKSUM, $value); - return false; - } - - $service = $this->getService(); - if (! empty($service)) { - try { - $callback = new Callback($service); - $callback->setOptions($this->getType()); - if (! $callback->isValid($value)) { - $this->error(self::SERVICE, $value); - return false; - } - } catch (Exception) { - $this->error(self::SERVICEFAILURE, $value); - return false; - } - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Csrf.php b/lib/laminas/laminas-validator/src/Csrf.php deleted file mode 100644 index 332d366ba..000000000 --- a/lib/laminas/laminas-validator/src/Csrf.php +++ /dev/null @@ -1,376 +0,0 @@ - 'The form submitted did not originate from the expected site', - ]; - - /** - * Actual hash used. - * - * @var mixed - */ - protected $hash; - - /** - * Static cache of the session names to generated hashes - * - * @todo unused, left here to avoid BC breaks - * @var array - */ - protected static $hashCache; - - /** - * Name of CSRF element (used to create non-colliding hashes) - * - * @var string - */ - protected $name = 'csrf'; - - /** - * Salt for CSRF token - * - * @var string - */ - protected $salt = 'salt'; - - /** @var SessionContainer */ - protected $session; - - /** - * TTL for CSRF token - * - * @var int|null - */ - protected $timeout = 300; - - /** - * Constructor - * - * @param array|Traversable $options - */ - public function __construct($options = []) - { - parent::__construct($options); - - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - - if (! is_array($options)) { - $options = (array) $options; - } - - foreach ($options as $key => $value) { - switch (strtolower($key)) { - case 'name': - $this->setName($value); - break; - case 'salt': - $this->setSalt($value); - break; - case 'session': - $this->setSession($value); - break; - case 'timeout': - $this->setTimeout($value); - break; - default: - // ignore unknown options - break; - } - } - } - - /** - * Does the provided token match the one generated? - * - * @param string $value - * @param mixed $context - * @return bool - */ - public function isValid($value, $context = null) - { - if (! is_string($value)) { - return false; - } - - $this->setValue($value); - - $tokenId = $this->getTokenIdFromHash($value); - $hash = $this->getValidationToken($tokenId); - - $tokenFromValue = $this->getTokenFromHash($value); - $tokenFromHash = $this->getTokenFromHash($hash); - - if (! $tokenFromValue || ! $tokenFromHash || ($tokenFromValue !== $tokenFromHash)) { - $this->error(self::NOT_SAME); - return false; - } - - return true; - } - - /** - * Set CSRF name - * - * @param string $name - * @return $this - */ - public function setName($name) - { - $this->name = (string) $name; - return $this; - } - - /** - * Get CSRF name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set session container - * - * @return $this - */ - public function setSession(SessionContainer $session) - { - $this->session = $session; - if ($this->hash) { - $this->initCsrfToken(); - } - return $this; - } - - /** - * Get session container - * - * Instantiate session container if none currently exists - * - * @return SessionContainer - */ - public function getSession() - { - if (null === $this->session) { - // Using fully qualified name, to ensure polyfill class alias is used - $this->session = new SessionContainer($this->getSessionName()); - } - return $this->session; - } - - /** - * Salt for CSRF token - * - * @param string $salt - * @return $this - */ - public function setSalt($salt) - { - $this->salt = (string) $salt; - return $this; - } - - /** - * Retrieve salt for CSRF token - * - * @return string - */ - public function getSalt() - { - return $this->salt; - } - - /** - * Retrieve CSRF token - * - * If no CSRF token currently exists, or should be regenerated, - * generates one. - * - * @param bool $regenerate default false - * @return string - */ - public function getHash($regenerate = false) - { - if ((null === $this->hash) || $regenerate) { - $this->generateHash(); - } - return $this->hash; - } - - /** - * Get session namespace for CSRF token - * - * Generates a session namespace based on salt, element name, and class. - * - * @return string - */ - public function getSessionName() - { - return str_replace('\\', '_', self::class) . '_' - . $this->getSalt() . '_' - . strtr($this->getName(), ['[' => '_', ']' => '']); - } - - /** - * Set timeout for CSRF session token - * - * @param int|null $ttl - * @return $this - */ - public function setTimeout($ttl) - { - $this->timeout = $ttl !== null ? (int) $ttl : null; - return $this; - } - - /** - * Get CSRF session token timeout - * - * @return int|null - */ - public function getTimeout() - { - return $this->timeout; - } - - /** - * Initialize CSRF token in session - * - * @return void - */ - protected function initCsrfToken() - { - $session = $this->getSession(); - $timeout = $this->getTimeout(); - if (null !== $timeout) { - $session->setExpirationSeconds($timeout); - } - - $hash = $this->getHash(); - $token = $this->getTokenFromHash($hash); - $tokenId = $this->getTokenIdFromHash($hash); - - if (! $session->tokenList) { - $session->tokenList = []; - } - $session->tokenList[$tokenId] = $token; - $session->hash = $hash; // @todo remove this, left for BC - } - - /** - * Generate CSRF token - * - * Generates CSRF token and stores both in {@link $hash} and element - * value. - * - * @return void - */ - protected function generateHash() - { - $token = md5($this->getSalt() . random_bytes(32) . $this->getName()); - - $this->hash = $this->formatHash($token, $this->generateTokenId()); - - $this->setValue($this->hash); - $this->initCsrfToken(); - } - - /** - * @return string - */ - protected function generateTokenId() - { - return md5(random_bytes(32)); - } - - /** - * Get validation token - * - * Retrieve token from session, if it exists. - * - * @param string $tokenId - * @return null|string - */ - protected function getValidationToken($tokenId = null) - { - $session = $this->getSession(); - - /** - * if no tokenId is passed we revert to the old behaviour - * - * @todo remove, here for BC - */ - if (! $tokenId && isset($session->hash)) { - return $session->hash; - } - - if ($tokenId && isset($session->tokenList[$tokenId])) { - return $this->formatHash($session->tokenList[$tokenId], $tokenId); - } - - return null; - } - - /** - * @return string - */ - protected function formatHash(string $token, string $tokenId) - { - return sprintf('%s-%s', $token, $tokenId); - } - - protected function getTokenFromHash(?string $hash): ?string - { - if (null === $hash) { - return null; - } - - $data = explode('-', $hash); - return $data[0] ?: null; - } - - protected function getTokenIdFromHash(string $hash): ?string - { - $data = explode('-', $hash); - - if (! isset($data[1])) { - return null; - } - - return $data[1]; - } -} diff --git a/lib/laminas/laminas-validator/src/Date.php b/lib/laminas/laminas-validator/src/Date.php deleted file mode 100644 index a74c12216..000000000 --- a/lib/laminas/laminas-validator/src/Date.php +++ /dev/null @@ -1,235 +0,0 @@ - 'Invalid type given. String, integer, array or DateTime expected', - self::INVALID_DATE => 'The input does not appear to be a valid date', - self::FALSEFORMAT => "The input does not fit the date format '%format%'", - ]; - - /** @var string[] */ - protected $messageVariables = [ - 'format' => 'format', - ]; - - /** @var string */ - protected $format = self::FORMAT_DEFAULT; - - /** @var bool */ - protected $strict = false; - - /** - * Sets validator options - * - * @param string|array|Traversable $options OPTIONAL - */ - public function __construct($options = []) - { - if ($options instanceof Traversable) { - $options = iterator_to_array($options); - } elseif (! is_array($options)) { - $options = func_get_args(); - $temp['format'] = array_shift($options); - $options = $temp; - } - - parent::__construct($options); - } - - /** - * Returns the format option - * - * @return string - */ - public function getFormat() - { - return $this->format; - } - - /** - * Sets the format option - * - * Format cannot be null. It will always default to 'Y-m-d', even - * if null is provided. - * - * @param string|null $format - * @return $this provides a fluent interface - * @todo validate the format - */ - public function setFormat($format = self::FORMAT_DEFAULT) - { - $this->format = empty($format) ? self::FORMAT_DEFAULT : $format; - return $this; - } - - public function setStrict(bool $strict): self - { - $this->strict = $strict; - return $this; - } - - public function isStrict(): bool - { - return $this->strict; - } - - /** - * Returns true if $value is a DateTimeInterface instance or can be converted into one. - * - * @param string|numeric|array|DateTimeInterface $value - * @return bool - */ - public function isValid($value) - { - $this->setValue($value); - - $date = $this->convertToDateTime($value); - if (! $date) { - $this->error(self::INVALID_DATE); - return false; - } - - if ($this->isStrict() && $date->format($this->getFormat()) !== $value) { - $this->error(self::FALSEFORMAT); - return false; - } - - return true; - } - - /** - * Attempts to convert an int, string, or array to a DateTime object - * - * @param string|numeric|array|DateTimeInterface $param - * @param bool $addErrors - * @return false|DateTime - */ - protected function convertToDateTime($param, $addErrors = true) - { - if ($param instanceof DateTime) { - return $param; - } - - if ($param instanceof DateTimeImmutable) { - return DateTime::createFromImmutable($param); - } - - $type = gettype($param); - switch ($type) { - case 'string': - return $this->convertString($param, $addErrors); - case 'integer': - return $this->convertInteger($param); - case 'double': - return $this->convertDouble($param); - case 'array': - return $this->convertArray($param, $addErrors); - } - - if ($addErrors) { - $this->error(self::INVALID); - } - - return false; - } - - /** - * Attempts to convert an integer into a DateTime object - * - * @param integer $value - * @return false|DateTime - */ - protected function convertInteger($value) - { - return DateTime::createFromFormat('U', (string) $value); - } - - /** - * Attempts to convert an double into a DateTime object - * - * @param double $value - * @return false|DateTime - */ - protected function convertDouble($value) - { - return DateTime::createFromFormat('U', (string) $value); - } - - /** - * Attempts to convert a string into a DateTime object - * - * @param string $value - * @param bool $addErrors - * @return false|DateTime - */ - protected function convertString($value, $addErrors = true) - { - $date = DateTime::createFromFormat($this->format, $value); - - // Invalid dates can show up as warnings (ie. "2007-02-99") - // and still return a DateTime object. - $errors = DateTime::getLastErrors(); - if ($errors === false) { - return $date; - } - - if ($errors['warning_count'] > 0) { - if ($addErrors) { - $this->error(self::FALSEFORMAT); - } - return false; - } - - return $date; - } - - /** - * Implodes the array into a string and proxies to {@link convertString()}. - * - * @param bool $addErrors - * @return false|DateTime - * @todo enhance the implosion - */ - protected function convertArray(array $value, $addErrors = true) - { - return $this->convertString(implode('-', $value), $addErrors); - } -} diff --git a/lib/laminas/laminas-validator/src/DateStep.php b/lib/laminas/laminas-validator/src/DateStep.php deleted file mode 100644 index ce28c1ed5..000000000 --- a/lib/laminas/laminas-validator/src/DateStep.php +++ /dev/null @@ -1,525 +0,0 @@ - 'Invalid type given. String, integer, array or DateTime expected', - self::INVALID_DATE => 'The input does not appear to be a valid date', - self::FALSEFORMAT => "The input does not fit the date format '%format%'", - self::NOT_STEP => 'The input is not a valid step', - ]; - - /** - * Optional base date value - * - * @var string|int|DateTimeInterface - */ - protected $baseValue = '1970-01-01T00:00:00Z'; - - /** - * Date step interval (defaults to 1 day). - * Uses the DateInterval specification. - * - * @var DateInterval - */ - protected $step; - - /** - * Optional timezone to be used when the baseValue - * and validation values do not contain timezone info - * - * @var DateTimeZone - */ - protected $timezone; - - /** - * Set default options for this instance - * - * @param string|array|Traversable $options - */ - public function __construct($options = []) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } elseif (! is_array($options)) { - $options = func_get_args(); - $temp = []; - $temp['baseValue'] = array_shift($options); - if (! empty($options)) { - $temp['step'] = array_shift($options); - } - if (! empty($options)) { - $temp['format'] = array_shift($options); - } - if (! empty($options)) { - $temp['timezone'] = array_shift($options); - } - - $options = $temp; - } - - if (! isset($options['step'])) { - $options['step'] = new DateInterval('P1D'); - } - if (! isset($options['timezone'])) { - $options['timezone'] = new DateTimeZone(date_default_timezone_get()); - } - - parent::__construct($options); - } - - /** - * Sets the base value from which the step should be computed - * - * @param string|int|DateTimeInterface $baseValue - * @return $this - */ - public function setBaseValue($baseValue) - { - $this->baseValue = $baseValue; - return $this; - } - - /** - * Returns the base value from which the step should be computed - * - * @return string|int|DateTimeInterface - */ - public function getBaseValue() - { - return $this->baseValue; - } - - /** - * Sets the step date interval - * - * @return $this - */ - public function setStep(DateInterval $step) - { - $this->step = $step; - return $this; - } - - /** - * Returns the step date interval - * - * @return DateInterval - */ - public function getStep() - { - return $this->step; - } - - /** - * Returns the timezone option - * - * @return DateTimeZone - */ - public function getTimezone() - { - return $this->timezone; - } - - /** - * Sets the timezone option - * - * @return $this - */ - public function setTimezone(DateTimeZone $timezone) - { - $this->timezone = $timezone; - return $this; - } - - /** - * Supports formats with ISO week (W) definitions - * - * @see Date::convertString() - * - * @param string $value - * @param bool $addErrors - * @return DateTime|false - */ - protected function convertString($value, $addErrors = true) - { - // Custom week format support - if ( - str_starts_with($this->format, 'Y-\WW') - && preg_match('/^([0-9]{4})\-W([0-9]{2})/', $value, $matches) - ) { - $date = new DateTime(); - $date->setISODate((int) $matches[1], (int) $matches[2]); - } else { - $date = DateTime::createFromFormat($this->format, $value, new DateTimeZone('UTC')); - } - - // Invalid dates can show up as warnings (ie. "2007-02-99") - // and still return a DateTime object. - $errors = DateTime::getLastErrors(); - if (is_array($errors) && $errors['warning_count'] > 0) { - if ($addErrors) { - $this->error(self::FALSEFORMAT); - } - return false; - } - - return $date; - } - - /** - * Returns true if a date is within a valid step - * - * @param string|int|DateTimeInterface $value - * @return bool - * @throws Exception\InvalidArgumentException - */ - public function isValid($value) - { - if (! parent::isValid($value)) { - return false; - } - - $valueDate = $this->convertToDateTime($value, false); // avoid duplicate errors - $baseDate = $this->convertToDateTime($this->baseValue, false); - - if (false === $valueDate || false === $baseDate) { - return false; - } - - $step = $this->getStep(); - - // Same date? - // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator - if ($valueDate == $baseDate) { - return true; - } - - // Optimization for simple intervals. - // Handle intervals of just one date or time unit. - $intervalParts = explode('|', $step->format('%y|%m|%d|%h|%i|%s')); - $intervalParts = array_map('intval', $intervalParts); - $partCounts = array_count_values($intervalParts); - - $unitKeys = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']; - $intervalParts = array_combine($unitKeys, $intervalParts); - - // Get absolute time difference to avoid special cases of missing/added time - $absoluteValueDate = new DateTime($valueDate->format('Y-m-d H:i:s'), new DateTimeZone('UTC')); - $absoluteBaseDate = new DateTime($baseDate->format('Y-m-d H:i:s'), new DateTimeZone('UTC')); - - $timeDiff = $absoluteValueDate->diff($absoluteBaseDate, true); - $diffParts = array_map('intval', explode('|', $timeDiff->format('%y|%m|%d|%h|%i|%s'))); - $diffParts = array_combine($unitKeys, $diffParts); - - if (5 === $partCounts[0]) { - // Find the unit with the non-zero interval - $intervalUnit = 'days'; - $stepValue = 1; - foreach ($intervalParts as $key => $value) { - if (0 !== $value) { - $intervalUnit = $key; - $stepValue = $value; - break; - } - } - - // Check date units - if (in_array($intervalUnit, ['years', 'months', 'days'])) { - switch ($intervalUnit) { - case 'years': - if ( - 0 === $diffParts['months'] && 0 === $diffParts['days'] - && 0 === $diffParts['hours'] && 0 === $diffParts['minutes'] - && 0 === $diffParts['seconds'] - ) { - if (($diffParts['years'] % $stepValue) === 0) { - return true; - } - } - break; - case 'months': - if ( - 0 === $diffParts['days'] && 0 === $diffParts['hours'] - && 0 === $diffParts['minutes'] && 0 === $diffParts['seconds'] - ) { - $months = ($diffParts['years'] * 12) + $diffParts['months']; - if (($months % $stepValue) === 0) { - return true; - } - } - break; - case 'days': - if ( - 0 === $diffParts['hours'] && 0 === $diffParts['minutes'] - && 0 === $diffParts['seconds'] - ) { - $days = (int) $timeDiff->format('%a'); // Total days - if (($days % $stepValue) === 0) { - return true; - } - } - break; - } - $this->error(self::NOT_STEP); - return false; - } - - // Check time units - if (in_array($intervalUnit, ['hours', 'minutes', 'seconds'])) { - // Simple test if $stepValue is 1. - if (1 === $stepValue) { - if ( - 'hours' === $intervalUnit - && 0 === $diffParts['minutes'] && 0 === $diffParts['seconds'] - ) { - return true; - } elseif ('minutes' === $intervalUnit && 0 === $diffParts['seconds']) { - return true; - } elseif ('seconds' === $intervalUnit) { - return true; - } - - $this->error(self::NOT_STEP); - - return false; - } - - // Simple test for same day, when using default baseDate - if ( - $baseDate->format('Y-m-d') === $valueDate->format('Y-m-d') - && $baseDate->format('Y-m-d') === '1970-01-01' - ) { - switch ($intervalUnit) { - case 'hours': - if (0 === $diffParts['minutes'] && 0 === $diffParts['seconds']) { - if (($diffParts['hours'] % $stepValue) === 0) { - return true; - } - } - break; - case 'minutes': - if (0 === $diffParts['seconds']) { - $minutes = ($diffParts['hours'] * 60) + $diffParts['minutes']; - if (($minutes % $stepValue) === 0) { - return true; - } - } - break; - case 'seconds': - $seconds = ($diffParts['hours'] * 60 * 60) - + ($diffParts['minutes'] * 60) - + $diffParts['seconds']; - if (($seconds % $stepValue) === 0) { - return true; - } - break; - } - $this->error(self::NOT_STEP); - return false; - } - } - } - - return $this->fallbackIncrementalIterationLogic($baseDate, $valueDate, $intervalParts, $diffParts, $step); - } - - /** - * Fall back to slower (but accurate) method for complex intervals. - * Keep adding steps to the base date until a match is found - * or until the value is exceeded. - * - * This is really slow if the interval is small, especially if the - * default base date of 1/1/1970 is used. We can skip a chunk of - * iterations by starting at the lower bound of steps needed to reach - * the target - * - * @param int[] $intervalParts - * @param int[] $diffParts - * @throws Exception\InvalidArgumentException - */ - private function fallbackIncrementalIterationLogic( - DateTimeInterface $baseDate, - DateTimeInterface $valueDate, - array $intervalParts, - array $diffParts, - DateInterval $step - ): bool { - [$minSteps, $requiredIterations] = $this->computeMinStepAndRequiredIterations($intervalParts, $diffParts); - $minimumInterval = $this->computeMinimumInterval($intervalParts, $minSteps); - $isIncrementalStepping = $baseDate < $valueDate; - - if (! ($baseDate instanceof DateTime || $baseDate instanceof DateTimeImmutable)) { - throw new Exception\InvalidArgumentException(sprintf( - 'Function %s requires the baseDate to be a DateTime or DateTimeImmutable instance.', - __FUNCTION__ - )); - } - - for ($offsetIterations = 0; $offsetIterations < $requiredIterations; $offsetIterations += 1) { - if ($isIncrementalStepping) { - $baseDate = $baseDate->add($minimumInterval); - } else { - $baseDate = $baseDate->sub($minimumInterval); - } - } - - while ( - ($isIncrementalStepping && $baseDate < $valueDate) - || (! $isIncrementalStepping && $baseDate > $valueDate) - ) { - if ($isIncrementalStepping) { - $baseDate = $baseDate->add($step); - } else { - $baseDate = $baseDate->sub($step); - } - - // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator - if ($baseDate == $valueDate) { - return true; - } - } - - $this->error(self::NOT_STEP); - - return false; - } - - /** - * Computes minimum interval to use for iterations while checking steps - * - * @param int[] $intervalParts - * @param int|float $minSteps - */ - private function computeMinimumInterval(array $intervalParts, $minSteps): DateInterval - { - return new DateInterval(sprintf( - 'P%dY%dM%dDT%dH%dM%dS', - $intervalParts['years'] * $minSteps, - $intervalParts['months'] * $minSteps, - $intervalParts['days'] * $minSteps, - $intervalParts['hours'] * $minSteps, - $intervalParts['minutes'] * $minSteps, - $intervalParts['seconds'] * $minSteps - )); - } - - /** - * @param int[] $intervalParts - * @param int[] $diffParts - * @return int[] (ordered tuple containing minimum steps and required step iterations - * @psalm-return array{0: int, 1: int} - */ - private function computeMinStepAndRequiredIterations(array $intervalParts, array $diffParts): array - { - $minSteps = $this->computeMinSteps($intervalParts, $diffParts); - - // If we use PHP_INT_MAX DateInterval::__construct falls over with a bad format error - // before we reach the max on 64 bit machines - $maxInteger = min(2 ** 31, PHP_INT_MAX); - // check for integer overflow and split $minimum interval if needed - $maximumInterval = max($intervalParts); - $requiredStepIterations = 1; - - if (($minSteps * $maximumInterval) > $maxInteger) { - $requiredStepIterations = ceil(($minSteps * $maximumInterval) / $maxInteger); - $minSteps = floor($minSteps / $requiredStepIterations); - } - - return [(int) $minSteps, $minSteps ? (int) $requiredStepIterations : 0]; - } - - /** - * Multiply the step interval by the lower bound of steps to reach the target - * - * @param int[] $intervalParts - * @param int[] $diffParts - * @return float|int - */ - private function computeMinSteps(array $intervalParts, array $diffParts) - { - $intervalMaxSeconds = $this->computeIntervalMaxSeconds($intervalParts); - - return 0 === $intervalMaxSeconds - ? 0 - : max(floor($this->computeDiffMinSeconds($diffParts) / $intervalMaxSeconds) - 1, 0); - } - - /** - * Get upper bound of the given interval in seconds - * Converts a given `$intervalParts` array into seconds - * - * @param int[] $intervalParts - */ - private function computeIntervalMaxSeconds(array $intervalParts): int - { - return ($intervalParts['years'] * 60 * 60 * 24 * 366) - + ($intervalParts['months'] * 60 * 60 * 24 * 31) - + ($intervalParts['days'] * 60 * 60 * 24) - + ($intervalParts['hours'] * 60 * 60) - + ($intervalParts['minutes'] * 60) - + $intervalParts['seconds']; - } - - /** - * Get lower bound of difference in secondss - * Converts a given `$diffParts` array into seconds - * - * @param int[] $diffParts - */ - private function computeDiffMinSeconds(array $diffParts): int - { - return ($diffParts['years'] * 60 * 60 * 24 * 365) - + ($diffParts['months'] * 60 * 60 * 24 * 28) - + ($diffParts['days'] * 60 * 60 * 24) - + ($diffParts['hours'] * 60 * 60) - + ($diffParts['minutes'] * 60) - + $diffParts['seconds']; - } -} diff --git a/lib/laminas/laminas-validator/src/Db/AbstractDb.php b/lib/laminas/laminas-validator/src/Db/AbstractDb.php deleted file mode 100755 index 495cdf113..000000000 --- a/lib/laminas/laminas-validator/src/Db/AbstractDb.php +++ /dev/null @@ -1,315 +0,0 @@ - Message templates */ - protected $messageTemplates = [ - self::ERROR_NO_RECORD_FOUND => 'No record matching the input was found', - self::ERROR_RECORD_FOUND => 'A record matching the input was found', - ]; - - /** - * Select object to use. can be set, or will be auto-generated - * - * @var Select - */ - protected $select; - - /** @var string */ - protected $schema; - - /** @var string */ - protected $table = ''; - - /** @var string */ - protected $field = ''; - - /** @var mixed */ - protected $exclude; - - /** - * Provides basic configuration for use with Laminas\Validator\Db Validators - * Setting $exclude allows a single record to be excluded from matching. - * Exclude can either be a String containing a where clause, or an array with `field` and `value` keys - * to define the where clause added to the sql. - * A database adapter may optionally be supplied to avoid using the registered default adapter. - * - * The following option keys are supported: - * 'table' => The database table to validate against - * 'schema' => The schema keys - * 'field' => The field to check for a match - * 'exclude' => An optional where clause or field/value pair to exclude from the query - * 'adapter' => An optional database adapter to use - * - * @param array|Traversable|Select $options Options to use for this validator - * @throws InvalidArgumentException - */ - public function __construct($options = null) - { - parent::__construct($options); - - if ($options instanceof Select) { - $this->setSelect($options); - return; - } - - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } elseif (func_num_args() > 1) { - $options = func_get_args(); - $firstArgument = array_shift($options); - if (is_array($firstArgument)) { - $temp = ArrayUtils::iteratorToArray($firstArgument); - } else { - $temp['table'] = $firstArgument; - } - - $temp['field'] = array_shift($options); - - if (! empty($options)) { - $temp['exclude'] = array_shift($options); - } - - if (! empty($options)) { - $temp['adapter'] = array_shift($options); - } - - $options = $temp; - } - - if (! array_key_exists('table', $options) && ! array_key_exists('schema', $options)) { - throw new Exception\InvalidArgumentException('Table or Schema option missing!'); - } - - if (! array_key_exists('field', $options)) { - throw new Exception\InvalidArgumentException('Field option missing!'); - } - - if (array_key_exists('adapter', $options)) { - $this->setAdapter($options['adapter']); - } - - if (array_key_exists('exclude', $options)) { - $this->setExclude($options['exclude']); - } - - $this->setField($options['field']); - if (array_key_exists('table', $options)) { - $this->setTable($options['table']); - } - - if (array_key_exists('schema', $options)) { - $this->setSchema($options['schema']); - } - } - - /** - * Returns the set adapter - * - * @throws RuntimeException When no database adapter is defined. - * @return DbAdapter - */ - public function getAdapter() - { - return $this->adapter; - } - - /** - * Sets a new database adapter - * - * @return self Provides a fluent interface - */ - public function setAdapter(DbAdapter $adapter) - { - return $this->setDbAdapter($adapter); - } - - /** - * Returns the set exclude clause - * - * @return string|array - */ - public function getExclude() - { - return $this->exclude; - } - - /** - * Sets a new exclude clause - * - * @param string|array $exclude - * @return $this Provides a fluent interface - */ - public function setExclude($exclude) - { - $this->exclude = $exclude; - $this->select = null; - return $this; - } - - /** - * Returns the set field - * - * @return string|array - */ - public function getField() - { - return $this->field; - } - - /** - * Sets a new field - * - * @param string $field - * @return $this - */ - public function setField($field) - { - $this->field = (string) $field; - $this->select = null; - return $this; - } - - /** - * Returns the set table - * - * @return string - */ - public function getTable() - { - return $this->table; - } - - /** - * Sets a new table - * - * @param string $table - * @return $this Provides a fluent interface - */ - public function setTable($table) - { - $this->table = (string) $table; - $this->select = null; - return $this; - } - - /** - * Returns the set schema - * - * @return string - */ - public function getSchema() - { - return $this->schema; - } - - /** - * Sets a new schema - * - * @param string $schema - * @return $this Provides a fluent interface - */ - public function setSchema($schema) - { - $this->schema = $schema; - $this->select = null; - return $this; - } - - /** - * Sets the select object to be used by the validator - * - * @return $this Provides a fluent interface - */ - public function setSelect(Select $select) - { - $this->select = $select; - return $this; - } - - /** - * Gets the select object to be used by the validator. - * If no select object was supplied to the constructor, - * then it will auto-generate one from the given table, - * schema, field, and adapter options. - * - * @return Select The Select object which will be used - */ - public function getSelect() - { - if ($this->select instanceof Select) { - return $this->select; - } - - // Build select object - $select = new Select(); - $tableIdentifier = new TableIdentifier($this->table, $this->schema); - $select->from($tableIdentifier)->columns([$this->field]); - $select->where->equalTo($this->field, null); - - if ($this->exclude !== null) { - if (is_array($this->exclude)) { - $select->where->notEqualTo( - $this->exclude['field'], - $this->exclude['value'] - ); - } else { - $select->where($this->exclude); - } - } - - $this->select = $select; - - return $this->select; - } - - /** - * Run query and returns matches, or null if no matches are found. - * - * @param string $value - * @return array when matches are found. - */ - protected function query($value) - { - $sql = new Sql($this->getAdapter()); - $select = $this->getSelect(); - $statement = $sql->prepareStatementForSqlObject($select); - $parameters = $statement->getParameterContainer(); - $parameters['where1'] = $value; - $result = $statement->execute(); - - return $result->current(); - } -} diff --git a/lib/laminas/laminas-validator/src/Db/NoRecordExists.php b/lib/laminas/laminas-validator/src/Db/NoRecordExists.php deleted file mode 100644 index 573a81ff8..000000000 --- a/lib/laminas/laminas-validator/src/Db/NoRecordExists.php +++ /dev/null @@ -1,36 +0,0 @@ -adapter) { - throw new Exception\RuntimeException('No database adapter present'); - } - - $valid = true; - $this->setValue($value); - - $result = $this->query($value); - if ($result) { - $valid = false; - $this->error(self::ERROR_RECORD_FOUND); - } - - return $valid; - } -} diff --git a/lib/laminas/laminas-validator/src/Db/RecordExists.php b/lib/laminas/laminas-validator/src/Db/RecordExists.php deleted file mode 100644 index bbc57db21..000000000 --- a/lib/laminas/laminas-validator/src/Db/RecordExists.php +++ /dev/null @@ -1,36 +0,0 @@ -adapter) { - throw new Exception\RuntimeException('No database adapter present'); - } - - $valid = true; - $this->setValue($value); - - $result = $this->query($value); - if (! $result) { - $valid = false; - $this->error(self::ERROR_NO_RECORD_FOUND); - } - - return $valid; - } -} diff --git a/lib/laminas/laminas-validator/src/Digits.php b/lib/laminas/laminas-validator/src/Digits.php deleted file mode 100644 index 34568a5c5..000000000 --- a/lib/laminas/laminas-validator/src/Digits.php +++ /dev/null @@ -1,66 +0,0 @@ - 'The input must contain only digits', - self::STRING_EMPTY => 'The input is an empty string', - self::INVALID => 'Invalid type given. String, integer or float expected', - ]; - - /** - * Returns true if and only if $value only contains digit characters - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value) && ! is_int($value) && ! is_float($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue((string) $value); - - if ('' === $this->getValue()) { - $this->error(self::STRING_EMPTY); - return false; - } - - if (null === static::$filter) { - static::$filter = new DigitsFilter(); - } - - if ($this->getValue() !== static::$filter->filter($this->getValue())) { - $this->error(self::NOT_DIGITS); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/EmailAddress.php b/lib/laminas/laminas-validator/src/EmailAddress.php deleted file mode 100644 index 65e27b22e..000000000 --- a/lib/laminas/laminas-validator/src/EmailAddress.php +++ /dev/null @@ -1,617 +0,0 @@ - */ - protected $messageTemplates = [ - self::INVALID => "Invalid type given. String expected", - self::INVALID_FORMAT => "The input is not a valid email address. Use the basic format local-part@hostname", - self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for the email address", - self::INVALID_MX_RECORD => "'%hostname%' does not appear to have any valid MX or A records for the email address", - self::INVALID_SEGMENT => "'%hostname%' is not in a routable network segment. The email address should not be resolved from public network", - self::DOT_ATOM => "'%localPart%' can not be matched against dot-atom format", - self::QUOTED_STRING => "'%localPart%' can not be matched against quoted-string format", - self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for the email address", - self::LENGTH_EXCEEDED => "The input exceeds the allowed length", - ]; - - // phpcs:enable - - /** @var array */ - protected $messageVariables = [ - 'hostname' => 'hostname', - 'localPart' => 'localPart', - ]; - - /** @var string */ - protected $hostname; - - /** @var string */ - protected $localPart; - - /** - * Returns the found mx record information - * - * @var array - */ - protected $mxRecord = []; - - /** - * Internal options array - * - * @var array - */ - protected $options = [ - 'useMxCheck' => false, - 'useDeepMxCheck' => false, - 'useDomainCheck' => true, - 'allow' => Hostname::ALLOW_DNS, - 'strict' => true, - 'hostnameValidator' => null, - ]; - - /** - * Instantiates hostname validator for local use - * - * The following additional option keys are supported: - * 'hostnameValidator' => A hostname validator, see Laminas\Validator\Hostname - * 'allow' => Options for the hostname validator, see Laminas\Validator\Hostname::ALLOW_* - * 'strict' => Whether to adhere to strictest requirements in the spec - * 'useMxCheck' => If MX check should be enabled, boolean - * 'useDeepMxCheck' => If a deep MX check should be done, boolean - * - * @param array|Traversable $options OPTIONAL - */ - public function __construct($options = []) - { - if (! is_array($options)) { - $options = func_get_args(); - $temp['allow'] = array_shift($options); - if (! empty($options)) { - $temp['useMxCheck'] = array_shift($options); - } - - if (! empty($options)) { - $temp['hostnameValidator'] = array_shift($options); - } - - $options = $temp; - } - - parent::__construct($options); - } - - /** - * Sets the validation failure message template for a particular key - * Adds the ability to set messages to the attached hostname validator - * - * @param string $messageString - * @param string $messageKey OPTIONAL - * @return AbstractValidator Provides a fluent interface - */ - public function setMessage($messageString, $messageKey = null) - { - if ($messageKey === null) { - $this->getHostnameValidator()->setMessage($messageString); - parent::setMessage($messageString); - return $this; - } - - if (! isset($this->messageTemplates[$messageKey])) { - $this->getHostnameValidator()->setMessage($messageString, $messageKey); - } else { - parent::setMessage($messageString, $messageKey); - } - - return $this; - } - - /** - * Returns the set hostname validator - * - * If was not previously set then lazy load a new one - * - * @return Hostname - */ - public function getHostnameValidator() - { - if (! isset($this->options['hostnameValidator'])) { - $this->options['hostnameValidator'] = new Hostname($this->getAllow()); - } - - return $this->options['hostnameValidator']; - } - - /** - * @param Hostname $hostnameValidator OPTIONAL - * @return $this Provides a fluent interface - */ - public function setHostnameValidator(?Hostname $hostnameValidator = null) - { - $this->options['hostnameValidator'] = $hostnameValidator; - - return $this; - } - - /** - * Returns the allow option of the attached hostname validator - * - * @return int - */ - public function getAllow() - { - return $this->options['allow']; - } - - /** - * Sets the allow option of the hostname validator to use - * - * @param int $allow - * @return $this Provides a fluent interface - */ - public function setAllow($allow) - { - $this->options['allow'] = $allow; - if (isset($this->options['hostnameValidator'])) { - $this->options['hostnameValidator']->setAllow($allow); - } - - return $this; - } - - /** - * Whether MX checking via getmxrr is supported or not - * - * @return bool - */ - public function isMxSupported() - { - return function_exists('getmxrr'); - } - - /** - * Returns the set validateMx option - * - * @return bool - */ - public function getMxCheck() - { - return $this->options['useMxCheck']; - } - - /** - * Set whether we check for a valid MX record via DNS - * - * This only applies when DNS hostnames are validated - * - * @param bool $mx Set allowed to true to validate for MX records, and false to not validate them - * @return $this Fluid Interface - */ - public function useMxCheck($mx) - { - $this->options['useMxCheck'] = (bool) $mx; - return $this; - } - - /** - * Returns the set deepMxCheck option - * - * @return bool - */ - public function getDeepMxCheck() - { - return $this->options['useDeepMxCheck']; - } - - /** - * Use deep validation for MX records - * - * @param bool $deep Set deep to true to perform a deep validation process for MX records - * @return $this Fluid Interface - */ - public function useDeepMxCheck($deep) - { - $this->options['useDeepMxCheck'] = (bool) $deep; - return $this; - } - - /** - * Returns the set domainCheck option - * - * @return bool - */ - public function getDomainCheck() - { - return $this->options['useDomainCheck']; - } - - /** - * Sets if the domain should also be checked - * or only the local part of the email address - * - * @param bool $domain - * @return $this Fluid Interface - */ - public function useDomainCheck($domain = true) - { - $this->options['useDomainCheck'] = (bool) $domain; - return $this; - } - - /** - * Returns if the given host is reserved - * - * The following addresses are seen as reserved - * '0.0.0.0/8', '10.0.0.0/8', '127.0.0.0/8' - * '100.64.0.0/10' - * '172.16.0.0/12' - * '198.18.0.0/15' - * '169.254.0.0/16', '192.168.0.0/16' - * '192.0.2.0/24', '192.88.99.0/24', '198.51.100.0/24', '203.0.113.0/24' - * '224.0.0.0/4', '240.0.0.0/4' - * - * @see http://en.wikipedia.org/wiki/Reserved_IP_addresses - * - * As of RFC5753 (JAN 2010), the following blocks are no longer reserved: - * - 128.0.0.0/16 - * - 191.255.0.0/16 - * - 223.255.255.0/24 - * @see http://tools.ietf.org/html/rfc5735#page-6 - * - * As of RFC6598 (APR 2012), the following blocks are now reserved: - * - 100.64.0.0/10 - * @see http://tools.ietf.org/html/rfc6598#section-7 - * - * @param string $host - * @return bool Returns false when minimal one of the given addresses is not reserved - */ - protected function isReserved($host) - { - if (! preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $host)) { - $host = gethostbynamel($host); - } else { - $host = [$host]; - } - - if (empty($host)) { - return false; - } - - foreach ($host as $server) { - // @codingStandardsIgnoreStart - // Search for 0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8 - if (!preg_match('/^(0|10|127)(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){3}$/', $server) && - // Search for 100.64.0.0/10 - !preg_match('/^100\.(6[0-4]|[7-9][0-9]|1[0-1][0-9]|12[0-7])(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){2}$/', $server) && - // Search for 172.16.0.0/12 - !preg_match('/^172\.(1[6-9]|2[0-9]|3[0-1])(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){2}$/', $server) && - // Search for 198.18.0.0/15 - !preg_match('/^198\.(1[8-9])(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){2}$/', $server) && - // Search for 169.254.0.0/16, 192.168.0.0/16 - !preg_match('/^(169\.254|192\.168)(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){2}$/', $server) && - // Search for 192.0.2.0/24, 192.88.99.0/24, 198.51.100.0/24, 203.0.113.0/24 - !preg_match('/^(192\.0\.2|192\.88\.99|198\.51\.100|203\.0\.113)\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$/', $server) && - // Search for 224.0.0.0/4, 240.0.0.0/4 - !preg_match('/^(2(2[4-9]|[3-4][0-9]|5[0-5]))(\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))){3}$/', $server) - ) { - return false; - } - // @codingStandardsIgnoreEnd - } - - return true; - } - - /** - * Internal method to validate the local part of the email address - * - * @return bool - */ - protected function validateLocalPart() - { - // First try to match the local part on the common dot-atom format - - // Dot-atom characters are: 1*atext *("." 1*atext) - // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*", - // "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~" - $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e'; - if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->localPart)) { - return true; - } - - if ($this->validateInternationalizedLocalPart($this->localPart)) { - return true; - } - - // Try quoted string format (RFC 5321 Chapter 4.1.2) - - // Quoted-string characters are: DQUOTE *(qtext/quoted-pair) DQUOTE - $qtext = '\x20-\x21\x23-\x5b\x5d-\x7e'; // %d32-33 / %d35-91 / %d93-126 - $quotedPair = '\x20-\x7e'; // %d92 %d32-126 - if (preg_match('/^"([' . $qtext . ']|\x5c[' . $quotedPair . '])*"$/', $this->localPart)) { - return true; - } - - $this->error(self::DOT_ATOM); - $this->error(self::QUOTED_STRING); - $this->error(self::INVALID_LOCAL_PART); - - return false; - } - - /** - * @param string $localPart Address local part to validate. - * @return bool - */ - protected function validateInternationalizedLocalPart($localPart) - { - if ( - extension_loaded('intl') - && false === UConverter::transcode($localPart, 'UTF-8', 'UTF-8') - ) { - // invalid utf? - return false; - } - - $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e'; - // RFC 6532 extends atext to include non-ascii utf - // @see https://tools.ietf.org/html/rfc6532#section-3.1 - $uatext = $atext . '\x{80}-\x{FFFF}'; - return (bool) preg_match('/^[' . $uatext . ']+(\x2e+[' . $uatext . ']+)*$/u', $localPart); - } - - /** - * Returns the found MX Record information after validation including weight for further processing - * - * @return array - */ - public function getMXRecord() - { - return $this->mxRecord; - } - - /** - * Internal method to validate the servers MX records - * - * @return bool|string[] - * @psalm-return bool|list - */ - protected function validateMXRecords() - { - $mxHosts = []; - $weight = []; - $result = getmxrr($this->hostname, $mxHosts, $weight); - if (! empty($mxHosts) && ! empty($weight)) { - $this->mxRecord = array_combine($mxHosts, $weight) ?: []; - } else { - $this->mxRecord = []; - } - - arsort($this->mxRecord); - - // Fallback to IPv4 hosts if no MX record found (RFC 2821 SS 5). - if (! $result) { - $result = gethostbynamel($this->hostname); - if (is_array($result)) { - $this->mxRecord = array_flip($result); - } - } - - if (! $result) { - $this->error(self::INVALID_MX_RECORD); - return $result; - } - - if (! $this->options['useDeepMxCheck']) { - return $result; - } - - $validAddress = false; - $reserved = true; - foreach (array_keys($this->mxRecord) as $hostname) { - $res = $this->isReserved($hostname); - if (! $res) { - $reserved = false; - } - - if (! is_string($hostname) || ! trim($hostname)) { - continue; - } - - if ( - ! $res - && (checkdnsrr($hostname, 'A') - || checkdnsrr($hostname, 'AAAA') - || checkdnsrr($hostname, 'A6')) - ) { - $validAddress = true; - break; - } - } - - if (! $validAddress) { - $result = false; - $error = $reserved ? self::INVALID_SEGMENT : self::INVALID_MX_RECORD; - $this->error($error); - } - - return $result; - } - - /** - * Internal method to validate the hostname part of the email address - * - * @return bool|string[] - * @psalm-return bool|list - */ - protected function validateHostnamePart() - { - $hostname = $this->getHostnameValidator()->setTranslator($this->getTranslator()) - ->isValid($this->hostname); - if (! $hostname) { - $this->error(self::INVALID_HOSTNAME); - // Get messages and errors from hostnameValidator - foreach ($this->getHostnameValidator()->getMessages() as $code => $message) { - $this->abstractOptions['messages'][$code] = $message; - } - } elseif ($this->options['useMxCheck']) { - // MX check on hostname - $hostname = $this->validateMXRecords(); - } - - return $hostname; - } - - /** - * Splits the given value in hostname and local part of the email address - * - * @param string $value Email address to be split - * @return bool Returns false when the email can not be split - */ - protected function splitEmailParts($value) - { - $value = is_string($value) ? $value : ''; - - // Split email address up and disallow '..' - if ( - str_contains($value, '..') - || ! preg_match('/^(.+)@([^@]+)$/', $value, $matches) - ) { - return false; - } - - $this->localPart = $matches[1]; - $this->hostname = $this->idnToAscii($matches[2]); - - return true; - } - - /** - * Defined by Laminas\Validator\ValidatorInterface - * - * Returns true if and only if $value is a valid email address - * according to RFC2822 - * - * @link http://www.ietf.org/rfc/rfc2822.txt RFC2822 - * @link http://www.columbia.edu/kermit/ascii.html US-ASCII characters - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $length = true; - $this->setValue($value); - - // Split email address up and disallow '..' - if (! $this->splitEmailParts($this->getValue())) { - $this->error(self::INVALID_FORMAT); - return false; - } - - if ($this->getOption('strict') && (strlen($this->localPart) > 64) || (strlen($this->hostname) > 255)) { - $length = false; - $this->error(self::LENGTH_EXCEEDED); - } - - // Match hostname part - $hostname = false; - if ($this->options['useDomainCheck']) { - $hostname = $this->validateHostnamePart(); - } - - $local = $this->validateLocalPart(); - - // If both parts valid, return true - return ($local && $length) && (! $this->options['useDomainCheck'] || $hostname); - } - - /** - * Safely convert UTF-8 encoded domain name to ASCII - * - * @param string $email the UTF-8 encoded email - * @return string - */ - protected function idnToAscii($email) - { - if (extension_loaded('intl')) { - if (defined('INTL_IDNA_VARIANT_UTS46')) { - return idn_to_ascii($email, 0, INTL_IDNA_VARIANT_UTS46) ?: $email; - } - return idn_to_ascii($email) ?: $email; - } - return $email; - } - - /** - * Safely convert ASCII encoded domain name to UTF-8 - * - * @param string $email the ASCII encoded email - * @return string - */ - protected function idnToUtf8($email) - { - if (strlen($email) === 0) { - return $email; - } - - if (extension_loaded('intl')) { - // The documentation does not clarify what kind of failure - // can happen in idn_to_utf8. One can assume if the source - // is not IDN encoded, it would fail, but it usually returns - // the source string in those cases. - // But not when the source string is long enough. - // Thus we default to source string ourselves. - if (defined('INTL_IDNA_VARIANT_UTS46')) { - return idn_to_utf8($email, 0, INTL_IDNA_VARIANT_UTS46) ?: $email; - } - return idn_to_utf8($email) ?: $email; - } - return $email; - } -} diff --git a/lib/laminas/laminas-validator/src/Exception/BadMethodCallException.php b/lib/laminas/laminas-validator/src/Exception/BadMethodCallException.php deleted file mode 100644 index 48ffcba69..000000000 --- a/lib/laminas/laminas-validator/src/Exception/BadMethodCallException.php +++ /dev/null @@ -1,7 +0,0 @@ - 'Invalid type given', - ]; - - /** @var array */ - protected $messageVariables = []; - - /** @var string */ - protected $valueDelimiter = ','; - - /** @var ValidatorInterface|null */ - protected $validator; - - /** @var bool */ - protected $breakOnFirstFailure = false; - - /** - * Sets the delimiter string that the values will be split upon - * - * @param string $delimiter - * @return $this - */ - public function setValueDelimiter($delimiter) - { - $this->valueDelimiter = $delimiter; - return $this; - } - - /** - * Returns the delimiter string that the values will be split upon - * - * @return string - */ - public function getValueDelimiter() - { - return $this->valueDelimiter; - } - - /** - * Set validator plugin manager - * - * @return void - */ - public function setValidatorPluginManager(ValidatorPluginManager $pluginManager) - { - $this->pluginManager = $pluginManager; - } - - /** - * Get validator plugin manager - * - * @return ValidatorPluginManager - */ - public function getValidatorPluginManager() - { - if (! $this->pluginManager) { - $this->pluginManager = new ValidatorPluginManager(new ServiceManager()); - } - - return $this->pluginManager; - } - - /** - * Sets the Validator for validating each value - * - * @param ValidatorInterface|ValidatorSpecification $validator - * @throws Exception\RuntimeException - * @return $this - */ - public function setValidator($validator) - { - if (is_array($validator)) { - if (! isset($validator['name'])) { - throw new Exception\RuntimeException( - 'Invalid validator specification provided; does not include "name" key' - ); - } - $name = $validator['name']; - $options = $validator['options'] ?? []; - /** @psalm-suppress MixedAssignment $validator */ - $validator = $this->getValidatorPluginManager()->get($name, $options); - } - - if (! $validator instanceof ValidatorInterface) { - throw new Exception\RuntimeException( - 'Invalid validator given' - ); - } - - $this->validator = $validator; - return $this; - } - - /** - * Gets the Validator for validating each value - * - * @return ValidatorInterface|null - */ - public function getValidator() - { - return $this->validator; - } - - /** - * Set break on first failure setting - * - * @param bool $break - * @return $this - */ - public function setBreakOnFirstFailure($break) - { - $this->breakOnFirstFailure = (bool) $break; - return $this; - } - - /** - * Get break on first failure setting - * - * @return bool - */ - public function isBreakOnFirstFailure() - { - return $this->breakOnFirstFailure; - } - - /** - * Defined by Laminas\Validator\ValidatorInterface - * - * Returns true if all values validate true - * - * @param mixed $value - * @param mixed $context Extra "context" to provide the composed validator - * @return bool - * @throws Exception\RuntimeException - */ - public function isValid($value, $context = null) - { - $this->setValue($value); - - if ($value instanceof Traversable) { - $value = ArrayUtils::iteratorToArray($value); - } - - if (is_array($value)) { - $values = $value; - } elseif (is_string($value)) { - $delimiter = $this->getValueDelimiter(); - // Skip explode if delimiter is null, - // used when value is expected to be either an - // array when multiple values and a string for - // single values (ie. MultiCheckbox form behavior) - $values = null !== $delimiter - ? explode($this->valueDelimiter, $value) - : [$value]; - } else { - $values = [$value]; - } - - $validator = $this->getValidator(); - - if (! $validator) { - throw new Exception\RuntimeException(sprintf( - '%s expects a validator to be set; none given', - __METHOD__ - )); - } - - foreach ($values as $value) { - if (! $validator->isValid($value, $context)) { - $this->abstractOptions['messages'][] = $validator->getMessages(); - - if ($this->isBreakOnFirstFailure()) { - return false; - } - } - } - - return ! $this->abstractOptions['messages']; - } -} diff --git a/lib/laminas/laminas-validator/src/File/Count.php b/lib/laminas/laminas-validator/src/File/Count.php deleted file mode 100644 index 1f8ee0960..000000000 --- a/lib/laminas/laminas-validator/src/File/Count.php +++ /dev/null @@ -1,257 +0,0 @@ - "Too many files, maximum '%max%' are allowed but '%count%' are given", - self::TOO_FEW => "Too few files, minimum '%min%' are expected but '%count%' are given", - ]; - - /** @var array Error message template variables */ - protected $messageVariables = [ - 'min' => ['options' => 'min'], - 'max' => ['options' => 'max'], - 'count' => 'count', - ]; - - /** - * Actual filecount - * - * @var int - */ - protected $count; - - /** - * Internal file array - * - * @var array - */ - protected $files; - - /** - * Options for this validator - * - * @var array - */ - protected $options = [ - 'min' => null, // Minimum file count, if null there is no minimum file count - 'max' => null, // Maximum file count, if null there is no maximum file count - ]; - - /** - * Sets validator options - * - * Min limits the file count, when used with max=null it is the maximum file count - * It also accepts an array with the keys 'min' and 'max' - * - * If $options is an integer, it will be used as maximum file count - * As Array is accepts the following keys: - * 'min': Minimum filecount - * 'max': Maximum filecount - * - * @param int|array|Traversable $options Options for the adapter - */ - public function __construct($options = null) - { - if (1 < func_num_args()) { - $args = func_get_args(); - $options = [ - 'min' => array_shift($args), - 'max' => array_shift($args), - ]; - } - - if (is_string($options) || is_numeric($options)) { - $options = ['max' => $options]; - } - - parent::__construct($options); - } - - /** - * Returns the minimum file count - * - * @return int - */ - public function getMin() - { - return $this->options['min']; - } - - /** - * Sets the minimum file count - * - * @param int|array $min The minimum file count - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException When min is greater than max. - */ - public function setMin($min) - { - if (is_array($min) && isset($min['min'])) { - $min = $min['min']; - } - - if (! is_numeric($min)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - $min = (int) $min; - if (($this->getMax() !== null) && ($min > $this->getMax())) { - throw new Exception\InvalidArgumentException( - "The minimum must be less than or equal to the maximum file count, but {$min} > {$this->getMax()}" - ); - } - - $this->options['min'] = $min; - return $this; - } - - /** - * Returns the maximum file count - * - * @return int - */ - public function getMax() - { - return $this->options['max']; - } - - /** - * Sets the maximum file count - * - * @param int|array $max The maximum file count - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException When max is smaller than min. - */ - public function setMax($max) - { - if (is_array($max) && isset($max['max'])) { - $max = $max['max']; - } - - if (! is_numeric($max)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - $max = (int) $max; - if (($this->getMin() !== null) && ($max < $this->getMin())) { - throw new Exception\InvalidArgumentException( - "The maximum must be greater than or equal to the minimum file count, but {$max} < {$this->getMin()}" - ); - } - - $this->options['max'] = $max; - return $this; - } - - /** - * Adds a file for validation - * - * @param string|array $file - * @return $this - */ - public function addFile($file) - { - if (is_string($file)) { - $file = [$file]; - } - - if (is_array($file)) { - foreach ($file as $name) { - if (! isset($this->files[$name]) && ! empty($name)) { - $this->files[$name] = $name; - } - } - } - - return $this; - } - - /** - * Returns true if and only if the file count of all checked files is at least min and - * not bigger than max (when max is not null). Attention: When checking with set min you - * must give all files with the first call, otherwise you will get a false. - * - * @param string|array $value Filenames to check for count - * @param array $file File data from \Laminas\File\Transfer\Transfer - * @return bool - */ - public function isValid($value, $file = null) - { - if (($file !== null) && ! array_key_exists('destination', $file)) { - $file['destination'] = dirname($value); - } - - if (($file !== null) && array_key_exists('tmp_name', $file)) { - $value = $file['destination'] . DIRECTORY_SEPARATOR . $file['name']; - } - - if (($file === null) || ! empty($file['tmp_name'])) { - $this->addFile($value); - } - - $this->count = count($this->files); - if (($this->getMax() !== null) && ($this->count > $this->getMax())) { - return $this->throwError($file, self::TOO_MANY); - } - - if (($this->getMin() !== null) && ($this->count < $this->getMin())) { - return $this->throwError($file, self::TOO_FEW); - } - - return true; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function throwError($file, $errorType) - { - if ($file !== null) { - if (is_array($file)) { - if (array_key_exists('name', $file)) { - $this->value = $file['name']; - } - } elseif (is_string($file)) { - $this->value = $file; - } - } - - $this->error($errorType); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/Crc32.php b/lib/laminas/laminas-validator/src/File/Crc32.php deleted file mode 100644 index 94963bf1f..000000000 --- a/lib/laminas/laminas-validator/src/File/Crc32.php +++ /dev/null @@ -1,110 +0,0 @@ - 'File does not match the given crc32 hashes', - self::NOT_DETECTED => 'A crc32 hash could not be evaluated for the given file', - self::NOT_FOUND => 'File is not readable or does not exist', - ]; - - /** - * Options for this validator - * - * @var string - */ - protected $options = [ - 'algorithm' => 'crc32', - 'hash' => null, - ]; - - /** - * Returns all set crc32 hashes - * - * @return array - */ - public function getCrc32() - { - return $this->getHash(); - } - - /** - * Sets the crc32 hash for one or multiple files - * - * @param string|array $options - * @return $this Provides a fluent interface - */ - public function setCrc32($options) - { - $this->setHash($options); - return $this; - } - - /** - * Adds the crc32 hash for one or multiple files - * - * @param string|array $options - * @return $this Provides a fluent interface - */ - public function addCrc32($options) - { - $this->addHash($options); - return $this; - } - - /** - * Returns true if and only if the given file confirms the set hash - * - * @param string|array $value Filename to check for hash - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(self::NOT_FOUND); - return false; - } - - $hashes = array_unique(array_keys($this->getHash())); - $filehash = hash_file('crc32', $fileInfo['file']); - if ($filehash === false) { - $this->error(self::NOT_DETECTED); - return false; - } - - foreach ($hashes as $hash) { - if ($filehash === $hash) { - return true; - } - } - - $this->error(self::DOES_NOT_MATCH); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/ExcludeExtension.php b/lib/laminas/laminas-validator/src/File/ExcludeExtension.php deleted file mode 100644 index 47741fc26..000000000 --- a/lib/laminas/laminas-validator/src/File/ExcludeExtension.php +++ /dev/null @@ -1,72 +0,0 @@ - 'File has an incorrect extension', - self::NOT_FOUND => 'File is not readable or does not exist', - ]; - - /** - * Returns true if and only if the file extension of $value is not included in the - * set extension list - * - * @param string|array $value Real file to check for extension - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - // Is file readable ? - if ( - ! $this->getAllowNonExistentFile() - && (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) - ) { - $this->error(self::NOT_FOUND); - return false; - } - - $this->setValue($fileInfo['filename']); - - $extension = substr($fileInfo['filename'], strrpos($fileInfo['filename'], '.') + 1); - $extensions = $this->getExtension(); - - if ($this->getCase() && (! in_array($extension, $extensions))) { - return true; - } elseif (! $this->getCase()) { - foreach ($extensions as $ext) { - if (strtolower($ext) === strtolower($extension)) { - $this->error(self::FALSE_EXTENSION); - return false; - } - } - - return true; - } - - $this->error(self::FALSE_EXTENSION); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/ExcludeMimeType.php b/lib/laminas/laminas-validator/src/File/ExcludeMimeType.php deleted file mode 100644 index f5a321c09..000000000 --- a/lib/laminas/laminas-validator/src/File/ExcludeMimeType.php +++ /dev/null @@ -1,97 +0,0 @@ - "File has an incorrect mimetype of '%type%'", - self::NOT_DETECTED => 'The mimetype could not be detected from the file', - self::NOT_READABLE => 'File is not readable or does not exist', - ]; - - /** - * Returns true if the mimetype of the file does not matche the given ones. Also parts - * of mimetypes can be checked. If you give for example "image" all image - * mime types will not be accepted like "image/gif", "image/jpeg" and so on. - * - * @param string|array $value Real file to check for mimetype - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file, true); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(self::NOT_READABLE); - return false; - } - - $mimefile = $this->getMagicFile(); - if (class_exists('finfo', false)) { - if (! $this->isMagicFileDisabled() && (! empty($mimefile) && empty($this->finfo))) { - $this->finfo = finfo_open(FILEINFO_MIME_TYPE, $mimefile); - } - - if (empty($this->finfo)) { - $this->finfo = finfo_open(FILEINFO_MIME_TYPE); - } - - $this->type = null; - if (! empty($this->finfo)) { - $this->type = finfo_file($this->finfo, $fileInfo['file']); - } - } - - if (empty($this->type) && $this->getHeaderCheck()) { - $this->type = $fileInfo['filetype']; - } - - if (empty($this->type)) { - $this->error(self::NOT_DETECTED); - return false; - } - - $mimetype = $this->getMimeType(true); - if (in_array($this->type, $mimetype)) { - $this->error(self::FALSE_TYPE); - return false; - } - - $types = explode('/', $this->type); - $types = array_merge($types, explode('-', $this->type)); - $types = array_merge($types, explode(';', $this->type)); - foreach ($mimetype as $mime) { - if (in_array($mime, $types)) { - $this->error(self::FALSE_TYPE); - return false; - } - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/File/Exists.php b/lib/laminas/laminas-validator/src/File/Exists.php deleted file mode 100644 index 80a27c975..000000000 --- a/lib/laminas/laminas-validator/src/File/Exists.php +++ /dev/null @@ -1,183 +0,0 @@ - 'File does not exist', - ]; - - /** - * Options for this validator - * - * @var array - */ - protected $options = [ - 'directory' => null, // internal list of directories - ]; - - /** @var array Error message template variables */ - protected $messageVariables = [ - 'directory' => ['options' => 'directory'], - ]; - - /** - * Sets validator options - * - * @param string|array|Traversable $options - */ - public function __construct($options = null) - { - if (is_string($options)) { - $options = explode(',', $options); - } - - if (is_array($options) && ! array_key_exists('directory', $options)) { - $options = ['directory' => $options]; - } - - parent::__construct($options); - } - - /** - * Returns the set file directories which are checked - * - * @param bool $asArray Returns the values as array; when false, a concatenated string is returned - * @return string|null - */ - public function getDirectory($asArray = false) - { - $asArray = (bool) $asArray; - $directory = $this->options['directory']; - if ($asArray && isset($directory)) { - $directory = explode(',', (string) $directory); - } - - return $directory; - } - - /** - * Sets the file directory which will be checked - * - * @param string|array $directory The directories to validate - * @return self Provides a fluent interface - */ - public function setDirectory($directory) - { - $this->options['directory'] = null; - $this->addDirectory($directory); - return $this; - } - - /** - * Adds the file directory which will be checked - * - * @param string|array $directory The directory to add for validation - * @return self Provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function addDirectory($directory) - { - $directories = $this->getDirectory(true); - if (! isset($directories)) { - $directories = []; - } - - if (is_string($directory)) { - $directory = explode(',', $directory); - } elseif (! is_array($directory)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - foreach ($directory as $content) { - if (empty($content) || ! is_string($content)) { - continue; - } - - $directories[] = trim($content); - } - $directories = array_unique($directories); - - // Sanity check to ensure no empty values - foreach ($directories as $key => $dir) { - if (empty($dir)) { - unset($directories[$key]); - } - } - - $this->options['directory'] = ! empty($directory) - ? implode(',', $directories) : null; - - return $this; - } - - /** - * Returns true if and only if the file already exists in the set directories - * - * @param string|array $value Real file to check for existence - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file, false, true); - - $this->setValue($fileInfo['filename']); - - $check = false; - $directories = $this->getDirectory(true); - if (! isset($directories)) { - $check = true; - if (! file_exists($fileInfo['file'])) { - $this->error(self::DOES_NOT_EXIST); - return false; - } - } else { - foreach ($directories as $directory) { - if (! isset($directory) || '' === $directory) { - continue; - } - - $check = true; - if (! file_exists($directory . DIRECTORY_SEPARATOR . $fileInfo['basename'])) { - $this->error(self::DOES_NOT_EXIST); - return false; - } - } - } - - if (! $check) { - $this->error(self::DOES_NOT_EXIST); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/File/Extension.php b/lib/laminas/laminas-validator/src/File/Extension.php deleted file mode 100644 index c977d9bcd..000000000 --- a/lib/laminas/laminas-validator/src/File/Extension.php +++ /dev/null @@ -1,242 +0,0 @@ - Error message templates */ - protected $messageTemplates = [ - self::FALSE_EXTENSION => 'File has an incorrect extension', - self::NOT_FOUND => 'File is not readable or does not exist', - ]; - - /** - * Options for this validator - * - * @var array - */ - protected $options = [ - 'case' => false, // Validate case sensitive - 'extension' => '', // List of extensions - 'allowNonExistentFile' => false, // Allow validation even if file does not exist - ]; - - /** @var array Error message template variables */ - protected $messageVariables = [ - 'extension' => ['options' => 'extension'], - ]; - - /** - * Sets validator options - * - * @param string|array|Traversable $options - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - - $case = null; - if (1 < func_num_args()) { - $case = func_get_arg(1); - } - - if (is_array($options)) { - if (isset($options['case'])) { - $case = $options['case']; - unset($options['case']); - } - - if (! array_key_exists('extension', $options)) { - $options = ['extension' => $options]; - } - } else { - $options = ['extension' => $options]; - } - - if ($case !== null) { - $options['case'] = $case; - } - - parent::__construct($options); - } - - /** - * Returns the case option - * - * @return bool - */ - public function getCase() - { - return $this->options['case']; - } - - /** - * Sets the case to use - * - * @param bool $case - * @return $this Provides a fluent interface - */ - public function setCase($case) - { - $this->options['case'] = (bool) $case; - return $this; - } - - /** - * Returns the set file extension - * - * @return array - */ - public function getExtension() - { - if ( - ! array_key_exists('extension', $this->options) - || ! is_string($this->options['extension']) - ) { - return []; - } - - return explode(',', $this->options['extension']); - } - - /** - * Sets the file extensions - * - * @param string|array $extension The extensions to validate - * @return $this Provides a fluent interface - */ - public function setExtension($extension) - { - $this->options['extension'] = null; - $this->addExtension($extension); - return $this; - } - - /** - * Adds the file extensions - * - * @param string|array $extension The extensions to add for validation - * @return $this Provides a fluent interface - */ - public function addExtension($extension) - { - $extensions = $this->getExtension(); - if (is_string($extension)) { - $extension = explode(',', $extension); - } - - foreach ($extension as $content) { - if (empty($content) || ! is_string($content)) { - continue; - } - - $extensions[] = trim($content); - } - - $extensions = array_unique($extensions); - - // Sanity check to ensure no empty values - foreach ($extensions as $key => $ext) { - if (empty($ext)) { - unset($extensions[$key]); - } - } - - $this->options['extension'] = implode(',', $extensions); - return $this; - } - - /** - * Returns whether or not to allow validation of non-existent files. - * - * @return bool - */ - public function getAllowNonExistentFile() - { - return $this->options['allowNonExistentFile']; - } - - /** - * Sets the flag indicating whether or not to allow validation of non-existent files. - * - * @param bool $flag Whether or not to allow validation of non-existent files. - * @return $this Provides a fluent interface - */ - public function setAllowNonExistentFile($flag) - { - $this->options['allowNonExistentFile'] = (bool) $flag; - return $this; - } - - /** - * Returns true if and only if the file extension of $value is included in the - * set extension list - * - * @param string|array $value Real file to check for extension - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - // Is file readable ? - if ( - ! $this->getAllowNonExistentFile() - && (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) - ) { - $this->error(self::NOT_FOUND); - return false; - } - - $this->setValue($fileInfo['filename']); - - $extension = substr($fileInfo['filename'], strrpos($fileInfo['filename'], '.') + 1); - $extensions = $this->getExtension(); - - if ($this->getCase() && (in_array($extension, $extensions))) { - return true; - } elseif (! $this->getCase()) { - foreach ($extensions as $ext) { - if (strtolower($ext) === strtolower($extension)) { - return true; - } - } - } - - $this->error(self::FALSE_EXTENSION); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/FileInformationTrait.php b/lib/laminas/laminas-validator/src/File/FileInformationTrait.php deleted file mode 100644 index 295027b93..000000000 --- a/lib/laminas/laminas-validator/src/File/FileInformationTrait.php +++ /dev/null @@ -1,164 +0,0 @@ -getLegacyFileInfo($file, $hasType, $hasBasename); - } - - if (is_array($value)) { - return $this->getSapiFileInfo($value, $hasType, $hasBasename); - } - - if ($value instanceof UploadedFileInterface) { - return $this->getPsr7FileInfo($value, $hasType, $hasBasename); - } - - return $this->getFileBasedFileInfo($value, $hasType, $hasBasename); - } - - /** - * Generate file information array with legacy Laminas_File_Transfer API - * - * @param array $file File data - * @param bool $hasType Return with filetype - * @param bool $hasBasename Basename is calculated from location path - * @return array - */ - private function getLegacyFileInfo( - array $file, - $hasType = false, - $hasBasename = false - ) { - $fileInfo = []; - - $fileInfo['filename'] = $file['name']; - $fileInfo['file'] = $file['tmp_name']; - - if ($hasBasename) { - $fileInfo['basename'] = basename($fileInfo['file']); - } - - if ($hasType) { - $fileInfo['filetype'] = $file['type']; - } - - return $fileInfo; - } - - /** - * Generate file information array with SAPI - * - * @param array $file File data from SAPI - * @param bool $hasType Return with filetype - * @param bool $hasBasename Filename is calculated from location path - * @return array - */ - private function getSapiFileInfo( - array $file, - $hasType = false, - $hasBasename = false - ) { - if (! isset($file['tmp_name']) || ! isset($file['name'])) { - throw new Exception\InvalidArgumentException( - 'Value array must be in $_FILES format' - ); - } - - $fileInfo = []; - - $fileInfo['file'] = $file['tmp_name']; - $fileInfo['filename'] = $file['name']; - - if ($hasBasename) { - $fileInfo['basename'] = basename($fileInfo['file']); - } - - if ($hasType) { - $fileInfo['filetype'] = $file['type']; - } - - return $fileInfo; - } - - /** - * Generate file information array with PSR-7 UploadedFileInterface - * - * @param bool $hasType Return with filetype - * @param bool $hasBasename Filename is calculated from location path - * @return array - */ - private function getPsr7FileInfo( - UploadedFileInterface $file, - $hasType = false, - $hasBasename = false - ) { - $fileInfo = []; - - $fileInfo['file'] = $file->getStream()->getMetadata('uri'); - $fileInfo['filename'] = $file->getClientFilename(); - - if ($hasBasename) { - $fileInfo['basename'] = basename($fileInfo['file']); - } - - if ($hasType) { - $fileInfo['filetype'] = $file->getClientMediaType(); - } - - return $fileInfo; - } - - /** - * Generate file information array with base method - * - * @param string $file File path - * @param bool $hasType Return with filetype - * @param bool $hasBasename Filename is calculated from location path - * @return array - */ - private function getFileBasedFileInfo( - $file, - $hasType = false, - $hasBasename = false - ) { - $fileInfo = []; - - $fileInfo['file'] = $file; - $fileInfo['filename'] = basename($fileInfo['file']); - - if ($hasBasename) { - $fileInfo['basename'] = basename($fileInfo['file']); - } - - if ($hasType) { - $fileInfo['filetype'] = null; - } - - return $fileInfo; - } -} diff --git a/lib/laminas/laminas-validator/src/File/FilesSize.php b/lib/laminas/laminas-validator/src/File/FilesSize.php deleted file mode 100644 index 25bd90250..000000000 --- a/lib/laminas/laminas-validator/src/File/FilesSize.php +++ /dev/null @@ -1,184 +0,0 @@ - "All files in sum should have a maximum size of '%max%' but '%size%' were detected", - self::TOO_SMALL => "All files in sum should have a minimum size of '%min%' but '%size%' were detected", - self::NOT_READABLE => 'One or more files can not be read', - ]; - - /** - * Internal file array - * - * @var array - */ - protected $files; - - /** - * Sets validator options - * - * Min limits the used disk space for all files, when used with max=null it is the maximum file size - * It also accepts an array with the keys 'min' and 'max' - * - * @param int|array|Traversable $options Options for this validator - * @throws InvalidArgumentException - */ - public function __construct($options = null) - { - $this->files = []; - $this->setSize(0); - - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } elseif (is_scalar($options)) { - $options = ['max' => $options]; - } elseif (! is_array($options)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - if (1 < func_num_args()) { - $argv = func_get_args(); - array_shift($argv); - $options['max'] = array_shift($argv); - if (! empty($argv)) { - $options['useByteString'] = array_shift($argv); - } - } - - parent::__construct($options); - } - - /** - * Returns true if and only if the disk usage of all files is at least min and - * not bigger than max (when max is not null). - * - * @param string|array $value Real file to check for size - * @param array $file File data from \Laminas\File\Transfer\Transfer - * @return bool - */ - public function isValid($value, $file = null) - { - if (is_string($value)) { - $value = [$value]; - } elseif (is_array($value) && isset($value['tmp_name'])) { - $value = [$value]; - } - - $min = $this->getMin(true); - $max = $this->getMax(true); - $size = $this->getSize(); - foreach ($value as $files) { - if (is_array($files)) { - if (! isset($files['tmp_name']) || ! isset($files['name'])) { - throw new Exception\InvalidArgumentException( - 'Value array must be in $_FILES format' - ); - } - $file = $files; - $files = $files['tmp_name']; - } - - // Is file readable ? - if (empty($files) || false === is_readable($files)) { - $this->throwError($file, self::NOT_READABLE); - continue; - } - - if (! isset($this->files[$files])) { - $this->files[$files] = $files; - } else { - // file already counted... do not count twice - continue; - } - - // limited to 2GB files - ErrorHandler::start(); - $size += filesize($files); - ErrorHandler::stop(); - $this->size = $size; - if (($max !== null) && ($max < $size)) { - if ($this->getByteString()) { - $this->options['max'] = $this->toByteString($max); - $this->size = $this->toByteString($size); - $this->throwError($file, self::TOO_BIG); - $this->options['max'] = $max; - $this->size = $size; - } else { - $this->throwError($file, self::TOO_BIG); - } - } - } - - // Check that aggregate files are >= minimum size - if (($min !== null) && ($size < $min)) { - if ($this->getByteString()) { - $this->options['min'] = $this->toByteString($min); - $this->size = $this->toByteString($size); - $this->throwError($file, self::TOO_SMALL); - $this->options['min'] = $min; - $this->size = $size; - } else { - $this->throwError($file, self::TOO_SMALL); - } - } - - if ($this->getMessages()) { - return false; - } - - return true; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function throwError($file, $errorType) - { - if ($file !== null) { - if (is_array($file)) { - if (array_key_exists('name', $file)) { - $this->value = $file['name']; - } - } elseif (is_string($file)) { - $this->value = $file; - } - } - - $this->error($errorType); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/Hash.php b/lib/laminas/laminas-validator/src/File/Hash.php deleted file mode 100644 index ed5afde80..000000000 --- a/lib/laminas/laminas-validator/src/File/Hash.php +++ /dev/null @@ -1,175 +0,0 @@ - 'File does not match the given hashes', - self::NOT_DETECTED => 'A hash could not be evaluated for the given file', - self::NOT_FOUND => 'File is not readable or does not exist', - ]; - - /** - * Options for this validator - * - * @var string - */ - protected $options = [ - 'algorithm' => 'crc32', - 'hash' => null, - ]; - - /** - * Sets validator options - * - * @param string|array $options - */ - public function __construct($options = null) - { - if ( - is_scalar($options) || - (is_array($options) && ! array_key_exists('hash', $options)) - ) { - $options = ['hash' => $options]; - } - - if (1 < func_num_args()) { - $options['algorithm'] = func_get_arg(1); - } - - parent::__construct($options); - } - - /** - * Returns the set hash values as array, the hash as key and the algorithm the value - * - * @return array - */ - public function getHash() - { - return $this->options['hash']; - } - - /** - * Sets the hash for one or multiple files - * - * @param string|array $options - * @return $this Provides a fluent interface - */ - public function setHash($options) - { - $this->options['hash'] = null; - $this->addHash($options); - - return $this; - } - - /** - * Adds the hash for one or multiple files - * - * @param string|array $options - * @throws Exception\InvalidArgumentException - * @return $this Provides a fluent interface - */ - public function addHash($options) - { - if (is_string($options)) { - $options = [$options]; - } elseif (! is_array($options)) { - throw new Exception\InvalidArgumentException('False parameter given'); - } - - $known = hash_algos(); - if (! isset($options['algorithm'])) { - $algorithm = $this->options['algorithm']; - } else { - $algorithm = $options['algorithm']; - unset($options['algorithm']); - } - - if (! in_array($algorithm, $known)) { - throw new Exception\InvalidArgumentException("Unknown algorithm '{$algorithm}'"); - } - - foreach ($options as $value) { - if (! is_string($value)) { - throw new Exception\InvalidArgumentException(sprintf( - 'Hash must be a string, %s received', - get_debug_type($value) - )); - } - $this->options['hash'][$value] = $algorithm; - } - - return $this; - } - - /** - * Returns true if and only if the given file confirms the set hash - * - * @param string|array $value File to check for hash - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(self::NOT_FOUND); - return false; - } - - $algos = array_unique(array_values($this->getHash())); - foreach ($algos as $algorithm) { - $filehash = hash_file($algorithm, $fileInfo['file']); - - if ($filehash === false) { - $this->error(self::NOT_DETECTED); - return false; - } - - if (isset($this->getHash()[$filehash]) && $this->getHash()[$filehash] === $algorithm) { - return true; - } - } - - $this->error(self::DOES_NOT_MATCH); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/ImageSize.php b/lib/laminas/laminas-validator/src/File/ImageSize.php deleted file mode 100644 index 91f478bb7..000000000 --- a/lib/laminas/laminas-validator/src/File/ImageSize.php +++ /dev/null @@ -1,377 +0,0 @@ - "Maximum allowed width for image should be '%maxwidth%' but '%width%' detected", - self::WIDTH_TOO_SMALL => "Minimum expected width for image should be '%minwidth%' but '%width%' detected", - self::HEIGHT_TOO_BIG => "Maximum allowed height for image should be '%maxheight%' but '%height%' detected", - self::HEIGHT_TOO_SMALL => "Minimum expected height for image should be '%minheight%' but '%height%' detected", - self::NOT_DETECTED => 'The size of image could not be detected', - self::NOT_READABLE => 'File is not readable or does not exist', - ]; - - /** @var array Error message template variables */ - protected $messageVariables = [ - 'minwidth' => ['options' => 'minWidth'], - 'maxwidth' => ['options' => 'maxWidth'], - 'minheight' => ['options' => 'minHeight'], - 'maxheight' => ['options' => 'maxHeight'], - 'width' => 'width', - 'height' => 'height', - ]; - - /** - * Detected width - * - * @var int - */ - protected $width; - - /** - * Detected height - * - * @var int - */ - protected $height; - - /** - * Options for this validator - * - * @var array - */ - protected $options = [ - 'minWidth' => null, // Minimum image width - 'maxWidth' => null, // Maximum image width - 'minHeight' => null, // Minimum image height - 'maxHeight' => null, // Maximum image height - ]; - - /** - * Sets validator options - * - * Accepts the following option keys: - * - minheight - * - minwidth - * - maxheight - * - maxwidth - * - * @param null|array|Traversable $options - */ - public function __construct($options = null) - { - if (1 < func_num_args()) { - if (! is_array($options)) { - $options = ['minWidth' => $options]; - } - - $argv = func_get_args(); - array_shift($argv); - $options['minHeight'] = array_shift($argv); - if (! empty($argv)) { - $options['maxWidth'] = array_shift($argv); - if (! empty($argv)) { - $options['maxHeight'] = array_shift($argv); - } - } - } - - parent::__construct($options); - } - - /** - * Returns the minimum allowed width - * - * @return int - */ - public function getMinWidth() - { - return $this->options['minWidth']; - } - - /** - * Sets the minimum allowed width - * - * @param int $minWidth - * @return $this Provides a fluid interface - * @throws Exception\InvalidArgumentException When minwidth is greater than maxwidth. - */ - public function setMinWidth($minWidth) - { - if (($this->getMaxWidth() !== null) && ($minWidth > $this->getMaxWidth())) { - throw new Exception\InvalidArgumentException( - 'The minimum image width must be less than or equal to the ' - . " maximum image width, but {$minWidth} > {$this->getMaxWidth()}" - ); - } - - $this->options['minWidth'] = (int) $minWidth; - return $this; - } - - /** - * Returns the maximum allowed width - * - * @return int - */ - public function getMaxWidth() - { - return $this->options['maxWidth']; - } - - /** - * Sets the maximum allowed width - * - * @param int $maxWidth - * @return $this Provides a fluid interface - * @throws Exception\InvalidArgumentException When maxwidth is less than minwidth. - */ - public function setMaxWidth($maxWidth) - { - if (($this->getMinWidth() !== null) && ($maxWidth < $this->getMinWidth())) { - throw new Exception\InvalidArgumentException( - 'The maximum image width must be greater than or equal to the ' - . "minimum image width, but {$maxWidth} < {$this->getMinWidth()}" - ); - } - - $this->options['maxWidth'] = (int) $maxWidth; - return $this; - } - - /** - * Returns the minimum allowed height - * - * @return int - */ - public function getMinHeight() - { - return $this->options['minHeight']; - } - - /** - * Sets the minimum allowed height - * - * @param int $minHeight - * @return $this Provides a fluid interface - * @throws Exception\InvalidArgumentException When minheight is greater than maxheight. - */ - public function setMinHeight($minHeight) - { - if (($this->getMaxHeight() !== null) && ($minHeight > $this->getMaxHeight())) { - throw new Exception\InvalidArgumentException( - 'The minimum image height must be less than or equal to the ' - . " maximum image height, but {$minHeight} > {$this->getMaxHeight()}" - ); - } - - $this->options['minHeight'] = (int) $minHeight; - return $this; - } - - /** - * Returns the maximum allowed height - * - * @return int - */ - public function getMaxHeight() - { - return $this->options['maxHeight']; - } - - /** - * Sets the maximum allowed height - * - * @param int $maxHeight - * @return $this Provides a fluid interface - * @throws Exception\InvalidArgumentException When maxheight is less than minheight. - */ - public function setMaxHeight($maxHeight) - { - if (($this->getMinHeight() !== null) && ($maxHeight < $this->getMinHeight())) { - throw new Exception\InvalidArgumentException( - 'The maximum image height must be greater than or equal to the ' - . "minimum image height, but {$maxHeight} < {$this->getMinHeight()}" - ); - } - - $this->options['maxHeight'] = (int) $maxHeight; - return $this; - } - - /** - * Returns the set minimum image sizes - * - * @return array - */ - public function getImageMin() - { - return ['minWidth' => $this->getMinWidth(), 'minHeight' => $this->getMinHeight()]; - } - - /** - * Returns the set maximum image sizes - * - * @return array - */ - public function getImageMax() - { - return ['maxWidth' => $this->getMaxWidth(), 'maxHeight' => $this->getMaxHeight()]; - } - - /** - * Returns the set image width sizes - * - * @return array - */ - public function getImageWidth() - { - return ['minWidth' => $this->getMinWidth(), 'maxWidth' => $this->getMaxWidth()]; - } - - /** - * Returns the set image height sizes - * - * @return array - */ - public function getImageHeight() - { - return ['minHeight' => $this->getMinHeight(), 'maxHeight' => $this->getMaxHeight()]; - } - - /** - * Sets the minimum image size - * - * @param array $options The minimum image dimensions - * @return $this Provides a fluent interface - */ - public function setImageMin($options) - { - $this->setOptions($options); - return $this; - } - - /** - * Sets the maximum image size - * - * @param array|Traversable $options The maximum image dimensions - * @return $this Provides a fluent interface - */ - public function setImageMax($options) - { - $this->setOptions($options); - return $this; - } - - /** - * Sets the minimum and maximum image width - * - * @param array $options The image width dimensions - * @return $this Provides a fluent interface - */ - public function setImageWidth($options) - { - $this->setImageMin($options); - $this->setImageMax($options); - - return $this; - } - - /** - * Sets the minimum and maximum image height - * - * @param array $options The image height dimensions - * @return $this Provides a fluent interface - */ - public function setImageHeight($options) - { - $this->setImageMin($options); - $this->setImageMax($options); - - return $this; - } - - /** - * Returns true if and only if the image size of $value is at least min and - * not bigger than max - * - * @param string|array $value Real file to check for image size - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(self::NOT_READABLE); - return false; - } - - ErrorHandler::start(); - $size = getimagesize($fileInfo['file']); - ErrorHandler::stop(); - - if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) { - $this->error(self::NOT_DETECTED); - return false; - } - - $this->width = $size[0]; - $this->height = $size[1]; - if ($this->width < $this->getMinWidth()) { - $this->error(self::WIDTH_TOO_SMALL); - } - - if (($this->getMaxWidth() !== null) && ($this->getMaxWidth() < $this->width)) { - $this->error(self::WIDTH_TOO_BIG); - } - - if ($this->height < $this->getMinHeight()) { - $this->error(self::HEIGHT_TOO_SMALL); - } - - if (($this->getMaxHeight() !== null) && ($this->getMaxHeight() < $this->height)) { - $this->error(self::HEIGHT_TOO_BIG); - } - - if ($this->getMessages()) { - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/File/IsCompressed.php b/lib/laminas/laminas-validator/src/File/IsCompressed.php deleted file mode 100644 index 86ce6164e..000000000 --- a/lib/laminas/laminas-validator/src/File/IsCompressed.php +++ /dev/null @@ -1,84 +0,0 @@ - "File is not compressed, '%type%' detected", - self::NOT_DETECTED => 'The mimetype could not be detected from the file', - self::NOT_READABLE => 'File is not readable or does not exist', - ]; - - /** - * Sets validator options - * - * @param string|array|Traversable $options - */ - public function __construct($options = []) - { - // http://hul.harvard.edu/ois/systems/wax/wax-public-help/mimetypes.htm - $default = [ - 'application/arj', - 'application/gnutar', - 'application/lha', - 'application/lzx', - 'application/vnd.ms-cab-compressed', - 'application/x-ace-compressed', - 'application/x-arc', - 'application/x-archive', - 'application/x-arj', - 'application/x-bzip', - 'application/x-bzip2', - 'application/x-cab-compressed', - 'application/x-compress', - 'application/x-compressed', - 'application/x-cpio', - 'application/x-debian-package', - 'application/x-eet', - 'application/x-gzip', - 'application/x-java-pack200', - 'application/x-lha', - 'application/x-lharc', - 'application/x-lzh', - 'application/x-lzma', - 'application/x-lzx', - 'application/x-rar', - 'application/x-sit', - 'application/x-stuffit', - 'application/x-tar', - 'application/zip', - 'application/x-zip', - 'application/zoo', - 'multipart/x-gzip', - ]; - - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - - if ($options === null) { - $options = []; - } - - parent::__construct($options); - - if (! $this->getMimeType()) { - $this->setMimeType($default); - } - } -} diff --git a/lib/laminas/laminas-validator/src/File/IsImage.php b/lib/laminas/laminas-validator/src/File/IsImage.php deleted file mode 100644 index ced192753..000000000 --- a/lib/laminas/laminas-validator/src/File/IsImage.php +++ /dev/null @@ -1,110 +0,0 @@ - "File is no image, '%type%' detected", - self::NOT_DETECTED => 'The mimetype could not be detected from the file', - self::NOT_READABLE => 'File is not readable or does not exist', - ]; - - /** - * Sets validator options - * - * @param array|Traversable|string $options - */ - public function __construct($options = []) - { - // http://www.iana.org/assignments/media-types/media-types.xhtml#image - $default = [ - 'application/cdf', - 'application/dicom', - 'application/fractals', - 'application/postscript', - 'application/vnd.hp-hpgl', - 'application/vnd.oasis.opendocument.graphics', - 'application/x-cdf', - 'application/x-cmu-raster', - 'application/x-ima', - 'application/x-inventor', - 'application/x-koan', - 'application/x-portable-anymap', - 'application/x-world-x-3dmf', - 'image/bmp', - 'image/c', - 'image/cgm', - 'image/fif', - 'image/gif', - 'image/heic', - 'image/heif', - 'image/jpeg', - 'image/jpm', - 'image/jpx', - 'image/jp2', - 'image/naplps', - 'image/pjpeg', - 'image/png', - 'image/svg', - 'image/svg+xml', - 'image/tiff', - 'image/vnd.adobe.photoshop', - 'image/vnd.djvu', - 'image/vnd.fpx', - 'image/vnd.net-fpx', - 'image/webp', - 'image/x-cmu-raster', - 'image/x-cmx', - 'image/x-coreldraw', - 'image/x-cpi', - 'image/x-emf', - 'image/x-ico', - 'image/x-icon', - 'image/x-jg', - 'image/x-ms-bmp', - 'image/x-niff', - 'image/x-pict', - 'image/x-pcx', - 'image/x-png', - 'image/x-portable-anymap', - 'image/x-portable-bitmap', - 'image/x-portable-greymap', - 'image/x-portable-pixmap', - 'image/x-quicktime', - 'image/x-rgb', - 'image/x-tiff', - 'image/x-unknown', - 'image/x-windows-bmp', - 'image/x-xpmi', - ]; - - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - - if ($options === null) { - $options = []; - } - - parent::__construct($options); - - if (! $this->getMimeType()) { - $this->setMimeType($default); - } - } -} diff --git a/lib/laminas/laminas-validator/src/File/Md5.php b/lib/laminas/laminas-validator/src/File/Md5.php deleted file mode 100644 index 4d48edf4e..000000000 --- a/lib/laminas/laminas-validator/src/File/Md5.php +++ /dev/null @@ -1,110 +0,0 @@ - 'File does not match the given md5 hashes', - self::NOT_DETECTED => 'An md5 hash could not be evaluated for the given file', - self::NOT_FOUND => 'File is not readable or does not exist', - ]; - - /** - * Options for this validator - * - * @var string - */ - protected $options = [ - 'algorithm' => 'md5', - 'hash' => null, - ]; - - /** - * Returns all set md5 hashes - * - * @return array - */ - public function getMd5() - { - return $this->getHash(); - } - - /** - * Sets the md5 hash for one or multiple files - * - * @param string|array $options - * @return Hash Provides a fluent interface - */ - public function setMd5($options) - { - $this->setHash($options); - return $this; - } - - /** - * Adds the md5 hash for one or multiple files - * - * @param string|array $options - * @return Hash Provides a fluent interface - */ - public function addMd5($options) - { - $this->addHash($options); - return $this; - } - - /** - * Returns true if and only if the given file confirms the set hash - * - * @param string|array $value Filename to check for hash - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(self::NOT_FOUND); - return false; - } - - $hashes = array_unique(array_keys($this->getHash())); - $filehash = hash_file('md5', $fileInfo['file']); - if ($filehash === false) { - $this->error(self::NOT_DETECTED); - return false; - } - - foreach ($hashes as $hash) { - if ($filehash === $hash) { - return true; - } - } - - $this->error(self::DOES_NOT_MATCH); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/MimeType.php b/lib/laminas/laminas-validator/src/File/MimeType.php deleted file mode 100644 index 8fea1d20a..000000000 --- a/lib/laminas/laminas-validator/src/File/MimeType.php +++ /dev/null @@ -1,416 +0,0 @@ - "File has an incorrect mimetype of '%type%'", - self::NOT_DETECTED => 'The mimetype could not be detected from the file', - self::NOT_READABLE => 'File is not readable or does not exist', - ]; - - /** @var array */ - protected $messageVariables = [ - 'type' => 'type', - ]; - - /** @var string */ - protected $type; - - /** - * Finfo object to use - * - * @var resource - */ - protected $finfo; - - /** - * If no environment variable 'MAGIC' is set, try and autodiscover it based on common locations - * - * @var array - */ - protected $magicFiles = [ - '/usr/share/misc/magic', - '/usr/share/misc/magic.mime', - '/usr/share/misc/magic.mgc', - '/usr/share/mime/magic', - '/usr/share/mime/magic.mime', - '/usr/share/mime/magic.mgc', - '/usr/share/file/magic', - '/usr/share/file/magic.mime', - '/usr/share/file/magic.mgc', - ]; - - /** - * Options for this validator - * - * @var array - */ - protected $options = [ - 'enableHeaderCheck' => false, // Allow header check - 'disableMagicFile' => false, // Disable usage of magicfile - 'magicFile' => null, // Magicfile to use - 'mimeType' => null, // Mimetype to allow - ]; - - /** - * Sets validator options - * - * Mimetype to accept - * - NULL means default PHP usage by using the environment variable 'magic' - * - FALSE means disabling searching for mimetype, should be used for PHP 5.3 - * - A string is the mimetype file to use - * - * @param string|array|Traversable $options - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } elseif (is_string($options)) { - $this->setMimeType($options); - $options = []; - } elseif (is_array($options)) { - if (isset($options['magicFile'])) { - $this->setMagicFile($options['magicFile']); - unset($options['magicFile']); - } - - if (isset($options['enableHeaderCheck'])) { - $this->enableHeaderCheck($options['enableHeaderCheck']); - unset($options['enableHeaderCheck']); - } - - if (array_key_exists('mimeType', $options)) { - $this->setMimeType($options['mimeType']); - unset($options['mimeType']); - } - - // Handle cases where mimetypes are interspersed with options, or - // options are simply an array of mime types - foreach (array_keys($options) as $key) { - if (! is_int($key)) { - continue; - } - $this->addMimeType($options[$key]); - unset($options[$key]); - } - } - - parent::__construct($options); - } - - /** - * Returns the actual set magicfile - * - * @return string - */ - public function getMagicFile() - { - if (null === $this->options['magicFile']) { - $magic = getenv('magic'); - if (! empty($magic)) { - $this->setMagicFile($magic); - if ($this->options['magicFile'] === null) { - $this->options['magicFile'] = false; - } - return $this->options['magicFile']; - } - - foreach ($this->magicFiles as $file) { - try { - $this->setMagicFile($file); - } catch (Exception\ExceptionInterface) { - // suppressing errors which are thrown due to open_basedir restrictions - continue; - } - - if ($this->options['magicFile'] !== null) { - return $this->options['magicFile']; - } - } - - if ($this->options['magicFile'] === null) { - $this->options['magicFile'] = false; - } - } - - return $this->options['magicFile']; - } - - /** - * Sets the magicfile to use - * if null, the MAGIC constant from php is used - * if the MAGIC file is erroneous, no file will be set - * if false, the default MAGIC file from PHP will be used - * - * @param string $file - * @throws Exception\RuntimeException When finfo can not read the magicfile. - * @throws Exception\InvalidArgumentException - * @throws Exception\InvalidMagicMimeFileException - * @return $this Provides fluid interface - */ - public function setMagicFile($file) - { - if ($file === false) { - $this->options['magicFile'] = false; - } elseif (empty($file)) { - $this->options['magicFile'] = null; - } elseif (! class_exists('finfo', false)) { - $this->options['magicFile'] = null; - throw new Exception\RuntimeException('Magicfile can not be set; there is no finfo extension installed'); - } elseif (! is_file($file) || ! is_readable($file)) { - throw new Exception\InvalidArgumentException(sprintf( - 'The given magicfile ("%s") could not be read', - $file - )); - } else { - ErrorHandler::start(E_NOTICE | E_WARNING); - $this->finfo = finfo_open(FILEINFO_MIME_TYPE, $file); - $error = ErrorHandler::stop(); - if (empty($this->finfo)) { - $this->finfo = null; - throw new Exception\InvalidMagicMimeFileException(sprintf( - 'The given magicfile ("%s") could not be used by ext/finfo', - $file - ), 0, $error); - } - $this->options['magicFile'] = $file; - } - - return $this; - } - - /** - * Disables usage of MagicFile - * - * @param bool $disable False disables usage of magic file; true enables it. - * @return self Provides fluid interface - */ - public function disableMagicFile($disable) - { - $this->options['disableMagicFile'] = (bool) $disable; - return $this; - } - - /** - * Is usage of MagicFile disabled? - * - * @return bool - */ - public function isMagicFileDisabled() - { - return $this->options['disableMagicFile']; - } - - /** - * Returns the Header Check option - * - * @return bool - */ - public function getHeaderCheck() - { - return $this->options['enableHeaderCheck']; - } - - /** - * Defines if the http header should be used - * Note that this is unsafe and therefor the default value is false - * - * @param bool $headerCheck - * @return $this Provides fluid interface - */ - public function enableHeaderCheck($headerCheck = true) - { - $this->options['enableHeaderCheck'] = (bool) $headerCheck; - return $this; - } - - /** - * Returns the set mimetypes - * - * @param bool $asArray Returns the values as array, when false a concatenated string is returned - * @return string|array - * @psalm-return ($asArray is true ? list : string) - */ - public function getMimeType($asArray = false) - { - $asArray = (bool) $asArray; - $mimetype = (string) $this->options['mimeType']; - if ($asArray) { - $mimetype = explode(',', $mimetype); - } - - return $mimetype; - } - - /** - * Sets the mimetypes - * - * @param string|array $mimetype The mimetypes to validate - * @return $this Provides a fluent interface - */ - public function setMimeType($mimetype) - { - $this->options['mimeType'] = null; - $this->addMimeType($mimetype); - return $this; - } - - /** - * Adds the mimetypes - * - * @param string|array $mimetype The mimetypes to add for validation - * @throws Exception\InvalidArgumentException - * @return $this Provides a fluent interface - */ - public function addMimeType($mimetype) - { - $mimetypes = $this->getMimeType(true); - - if (is_string($mimetype)) { - $mimetype = explode(',', $mimetype); - } elseif (! is_array($mimetype)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - if (isset($mimetype['magicFile'])) { - unset($mimetype['magicFile']); - } - - foreach ($mimetype as $content) { - if (empty($content) || ! is_string($content)) { - continue; - } - $mimetypes[] = trim($content); - } - $mimetypes = array_unique($mimetypes); - - // Sanity check to ensure no empty values - foreach ($mimetypes as $key => $mt) { - if (empty($mt)) { - unset($mimetypes[$key]); - } - } - - $this->options['mimeType'] = implode(',', $mimetypes); - - return $this; - } - - /** - * Defined by Laminas\Validator\ValidatorInterface - * - * Returns true if the mimetype of the file matches the given ones. Also parts - * of mimetypes can be checked. If you give for example "image" all image - * mime types will be accepted like "image/gif", "image/jpeg" and so on. - * - * @param string|array $value Real file to check for mimetype - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file, true); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(static::NOT_READABLE); - return false; - } - - $mimefile = $this->getMagicFile(); - if (class_exists('finfo', false)) { - if (! $this->isMagicFileDisabled() && (! empty($mimefile) && empty($this->finfo))) { - ErrorHandler::start(E_NOTICE | E_WARNING); - $this->finfo = finfo_open(FILEINFO_MIME_TYPE, $mimefile); - ErrorHandler::stop(); - } - - if (empty($this->finfo)) { - ErrorHandler::start(E_NOTICE | E_WARNING); - $this->finfo = finfo_open(FILEINFO_MIME_TYPE); - ErrorHandler::stop(); - } - - $this->type = null; - if (! empty($this->finfo)) { - $this->type = finfo_file($this->finfo, $fileInfo['file']); - unset($this->finfo); - } - } - - if (empty($this->type) && $this->getHeaderCheck()) { - $this->type = $fileInfo['filetype']; - } - - if (empty($this->type)) { - $this->error(static::NOT_DETECTED); - return false; - } - - $mimetype = $this->getMimeType(true); - if (in_array($this->type, $mimetype)) { - return true; - } - - $types = explode('/', $this->type); - $types = array_merge($types, explode('-', $this->type)); - $types = array_merge($types, explode(';', $this->type)); - foreach ($mimetype as $mime) { - if (in_array($mime, $types)) { - return true; - } - } - - $this->error(static::FALSE_TYPE); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/NotExists.php b/lib/laminas/laminas-validator/src/File/NotExists.php deleted file mode 100644 index 0ed8f2f18..000000000 --- a/lib/laminas/laminas-validator/src/File/NotExists.php +++ /dev/null @@ -1,68 +0,0 @@ - 'File exists', - ]; - - /** - * Returns true if and only if the file does not exist in the set destinations - * - * @param string|array $value Real file to check for existence - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file, false, true); - - $this->setValue($fileInfo['filename']); - - $check = false; - $directories = $this->getDirectory(true); - if (! isset($directories)) { - $check = true; - if (file_exists($fileInfo['file'])) { - $this->error(self::DOES_EXIST); - return false; - } - } else { - foreach ($directories as $directory) { - if (! isset($directory) || '' === $directory) { - continue; - } - - $check = true; - if (file_exists($directory . DIRECTORY_SEPARATOR . $fileInfo['basename'])) { - $this->error(self::DOES_EXIST); - return false; - } - } - } - - if (! $check) { - $this->error(self::DOES_EXIST); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/File/Sha1.php b/lib/laminas/laminas-validator/src/File/Sha1.php deleted file mode 100644 index da90c45b7..000000000 --- a/lib/laminas/laminas-validator/src/File/Sha1.php +++ /dev/null @@ -1,110 +0,0 @@ - 'File does not match the given sha1 hashes', - self::NOT_DETECTED => 'A sha1 hash could not be evaluated for the given file', - self::NOT_FOUND => 'File is not readable or does not exist', - ]; - - /** - * Options for this validator - * - * @var string - */ - protected $options = [ - 'algorithm' => 'sha1', - 'hash' => null, - ]; - - /** - * Returns all set sha1 hashes - * - * @return array - */ - public function getSha1() - { - return $this->getHash(); - } - - /** - * Sets the sha1 hash for one or multiple files - * - * @param string|array $options - * @return Hash Provides a fluent interface - */ - public function setSha1($options) - { - $this->setHash($options); - return $this; - } - - /** - * Adds the sha1 hash for one or multiple files - * - * @param string|array $options - * @return Hash Provides a fluent interface - */ - public function addSha1($options) - { - $this->addHash($options); - return $this; - } - - /** - * Returns true if and only if the given file confirms the set hash - * - * @param (int|string)[]|string $value Filename to check for hash - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(self::NOT_FOUND); - return false; - } - - $hashes = array_unique(array_keys($this->getHash())); - $filehash = hash_file('sha1', $fileInfo['file']); - if ($filehash === false) { - $this->error(self::NOT_DETECTED); - return false; - } - - foreach ($hashes as $hash) { - if ($filehash === $hash) { - return true; - } - } - - $this->error(self::DOES_NOT_MATCH); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/Size.php b/lib/laminas/laminas-validator/src/File/Size.php deleted file mode 100644 index d3dd64df1..000000000 --- a/lib/laminas/laminas-validator/src/File/Size.php +++ /dev/null @@ -1,359 +0,0 @@ - "Maximum allowed size for file is '%max%' but '%size%' detected", - self::TOO_SMALL => "Minimum expected size for file is '%min%' but '%size%' detected", - self::NOT_FOUND => 'File is not readable or does not exist', - ]; - - /** @var array Error message template variables */ - protected $messageVariables = [ - 'min' => ['options' => 'min'], - 'max' => ['options' => 'max'], - 'size' => 'size', - ]; - - /** - * Detected size - * - * @var int - */ - protected $size; - - /** - * Options for this validator - * - * @var array - */ - protected $options = [ - 'min' => null, // Minimum file size, if null there is no minimum - 'max' => null, // Maximum file size, if null there is no maximum - 'useByteString' => true, // Use byte string? - ]; - - /** - * Sets validator options - * - * If $options is an integer, it will be used as maximum file size - * As Array is accepts the following keys: - * 'min': Minimum file size - * 'max': Maximum file size - * 'useByteString': Use bytestring or real size for messages - * - * @param int|array|Traversable $options Options for the adapter - */ - public function __construct($options = null) - { - if (is_string($options) || is_numeric($options)) { - $options = ['max' => $options]; - } - - if (1 < func_num_args()) { - $argv = func_get_args(); - array_shift($argv); - $options['max'] = array_shift($argv); - if (! empty($argv)) { - $options['useByteString'] = array_shift($argv); - } - } - - parent::__construct($options); - } - - /** - * Should messages return bytes as integer or as string in SI notation - * - * @param bool $byteString Use bytestring ? - * @return self - */ - public function useByteString($byteString = true) - { - $this->options['useByteString'] = (bool) $byteString; - return $this; - } - - /** - * Will bytestring be used? - * - * @return bool - */ - public function getByteString() - { - return $this->options['useByteString']; - } - - /** - * Returns the minimum file size - * - * @param bool $raw Whether or not to force return of the raw value (defaults off) - * @return int|string - */ - public function getMin($raw = false) - { - $min = $this->options['min']; - if (! $raw && $this->getByteString()) { - $min = $this->toByteString($min); - } - - return $min; - } - - /** - * Sets the minimum file size - * - * File size can be an integer or a byte string - * This includes 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' - * For example: 2000, 2MB, 0.2GB - * - * @param int|string $min The minimum file size - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException When min is greater than max. - */ - public function setMin($min) - { - if (! is_string($min) && ! is_numeric($min)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - $min = (int) $this->fromByteString($min); - $max = $this->getMax(true); - if (($max !== null) && ($min > $max)) { - throw new Exception\InvalidArgumentException( - "The minimum must be less than or equal to the maximum file size, but $min > $max" - ); - } - - $this->options['min'] = $min; - return $this; - } - - /** - * Returns the maximum file size - * - * @param bool $raw Whether or not to force return of the raw value (defaults off) - * @return int|string - */ - public function getMax($raw = false) - { - $max = $this->options['max']; - if (! $raw && $this->getByteString()) { - $max = $this->toByteString($max); - } - - return $max; - } - - /** - * Sets the maximum file size - * - * File size can be an integer or a byte string - * This includes 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' - * For example: 2000, 2MB, 0.2GB - * - * @param int|string $max The maximum file size - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException When max is smaller than min. - */ - public function setMax($max) - { - if (! is_string($max) && ! is_numeric($max)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - $max = (int) $this->fromByteString($max); - $min = $this->getMin(true); - if (($min !== null) && ($max < $min)) { - throw new Exception\InvalidArgumentException( - "The maximum must be greater than or equal to the minimum file size, but $max < $min" - ); - } - - $this->options['max'] = $max; - return $this; - } - - /** - * Retrieve current detected file size - * - * @return int - */ - protected function getSize() - { - return $this->size; - } - - /** - * Set current size - * - * @param int $size - * @return $this - */ - protected function setSize($size) - { - $this->size = $size; - return $this; - } - - /** - * Returns true if and only if the file size of $value is at least min and - * not bigger than max (when max is not null). - * - * @param string|array $value File to check for size - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(self::NOT_FOUND); - return false; - } - - // limited to 4GB files - ErrorHandler::start(); - $size = sprintf('%u', filesize($fileInfo['file'])); - ErrorHandler::stop(); - $this->size = $size; - - // Check to see if it's smaller than min size - $min = $this->getMin(true); - $max = $this->getMax(true); - if (($min !== null) && ($size < $min)) { - if ($this->getByteString()) { - $this->options['min'] = $this->toByteString($min); - $this->size = $this->toByteString($size); - $this->error(self::TOO_SMALL); - $this->options['min'] = $min; - $this->size = $size; - } else { - $this->error(self::TOO_SMALL); - } - } - - // Check to see if it's larger than max size - if (($max !== null) && ($max < $size)) { - if ($this->getByteString()) { - $this->options['max'] = $this->toByteString($max); - $this->size = $this->toByteString($size); - $this->error(self::TOO_BIG); - $this->options['max'] = $max; - $this->size = $size; - } else { - $this->error(self::TOO_BIG); - } - } - - if ($this->getMessages()) { - return false; - } - - return true; - } - - /** - * Returns the formatted size - * - * @param int $size - * @return string - */ - protected function toByteString($size) - { - $sizes = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - for ($i = 0; $size >= 1024 && $i < 9; $i++) { - $size /= 1024; - } - - return round($size, 2) . $sizes[$i]; - } - - /** - * Returns the unformatted size - * - * @param string $size - * @return float|int|string - */ - protected function fromByteString($size) - { - if (is_numeric($size)) { - return (int) $size; - } - - $type = trim(substr($size, -2, 1)); - - $value = substr($size, 0, -1); - if (! is_numeric($value)) { - $value = trim(substr($value, 0, -1)); - } - - switch (strtoupper($type)) { - case 'Y': - $value *= 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024; - break; - case 'Z': - $value *= 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024; - break; - case 'E': - $value *= 1024 * 1024 * 1024 * 1024 * 1024 * 1024; - break; - case 'P': - $value *= 1024 * 1024 * 1024 * 1024 * 1024; - break; - case 'T': - $value *= 1024 * 1024 * 1024 * 1024; - break; - case 'G': - $value *= 1024 * 1024 * 1024; - break; - case 'M': - $value *= 1024 * 1024; - break; - case 'K': - $value *= 1024; - break; - default: - break; - } - - return $value; - } -} diff --git a/lib/laminas/laminas-validator/src/File/Upload.php b/lib/laminas/laminas-validator/src/File/Upload.php deleted file mode 100644 index 10a0f2f3e..000000000 --- a/lib/laminas/laminas-validator/src/File/Upload.php +++ /dev/null @@ -1,270 +0,0 @@ - Error message templates */ - protected $messageTemplates = [ - self::INI_SIZE => "File '%value%' exceeds upload_max_filesize directive in php.ini", - self::FORM_SIZE => "File '%value%' exceeds the MAX_FILE_SIZE directive that was " - . 'specified in the HTML form', - self::PARTIAL => "File '%value%' was only partially uploaded", - self::NO_FILE => "File '%value%' was not uploaded", - self::NO_TMP_DIR => "Missing a temporary folder to store '%value%'", - self::CANT_WRITE => "Failed to write file '%value%' to disk", - self::EXTENSION => "A PHP extension stopped uploading the file '%value%'", - self::ATTACK => "File '%value%' was illegally uploaded. This could be a possible attack", - self::FILE_NOT_FOUND => "File '%value%' was not found", - self::UNKNOWN => "Unknown error while uploading file '%value%'", - ]; - - /** @var array */ - protected $options = [ - 'files' => [], - ]; - - /** - * Sets validator options - * - * The array $files must be given in syntax of Laminas\File\Transfer\Transfer to be checked - * If no files are given the $_FILES array will be used automatically. - * NOTE: This validator will only work with HTTP POST uploads! - * - * @param array|Traversable $options Array of files in syntax of \Laminas\File\Transfer\Transfer - */ - public function __construct($options = []) - { - if (is_array($options) && ! array_key_exists('files', $options)) { - $options = ['files' => $options]; - } - - parent::__construct($options); - } - - /** - * Returns the array of set files - * - * @param string $file (Optional) The file to return in detail - * @return array - * @throws Exception\InvalidArgumentException If file is not found. - */ - public function getFiles($file = null) - { - if ($file !== null) { - $return = []; - foreach ($this->options['files'] as $name => $content) { - if ($name === $file) { - $return[$file] = $this->options['files'][$name]; - } - - if ($content instanceof UploadedFileInterface) { - if ($content->getClientFilename() === $file) { - $return[$name] = $this->options['files'][$name]; - } - } elseif ($content['name'] === $file) { - $return[$name] = $this->options['files'][$name]; - } - } - - if (! $return) { - throw new Exception\InvalidArgumentException("The file '$file' was not found"); - } - - return $return; - } - - return $this->options['files']; - } - - /** - * Sets the files to be checked - * - * @param array $files The files to check in syntax of \Laminas\File\Transfer\Transfer - * @return $this Provides a fluent interface - */ - public function setFiles($files = []) - { - if ( - null === $files - || ((is_countable($files)) - && count($files) === 0) - ) { - $this->options['files'] = $_FILES; - } else { - $this->options['files'] = $files; - } - - if ($this->options['files'] === null) { - $this->options['files'] = []; - } - - foreach ($this->options['files'] as $file => $content) { - if ( - ! $content instanceof UploadedFileInterface - && ! isset($content['error']) - ) { - unset($this->options['files'][$file]); - } - } - - return $this; - } - - /** - * Returns true if and only if the file was uploaded without errors - * - * @param string $value Single file to check for upload errors, when giving null the $_FILES array - * from initialization will be used - * @param mixed $file - * @return bool - */ - public function isValid($value, $file = null) - { - $files = []; - $this->setValue($value); - if (array_key_exists($value, $this->getFiles())) { - $files = array_merge($files, $this->getFiles($value)); - } else { - foreach ($this->getFiles() as $file => $content) { - if ($content instanceof UploadedFileInterface) { - if ($content->getClientFilename() === $value) { - $files = array_merge($files, $this->getFiles($file)); - } - - // PSR cannot search by tmp_name because it does not have - // a public interface to get it, only user defined name - // from form field. - continue; - } - - if (isset($content['name']) && ($content['name'] === $value)) { - $files = array_merge($files, $this->getFiles($file)); - } - - if (isset($content['tmp_name']) && ($content['tmp_name'] === $value)) { - $files = array_merge($files, $this->getFiles($file)); - } - } - } - - if (empty($files)) { - return $this->throwError($file, self::FILE_NOT_FOUND); - } - - foreach ($files as $file => $content) { - $this->value = $file; - $error = $content instanceof UploadedFileInterface - ? $content->getError() - : $content['error']; - - switch ($error) { - case 0: - if ($content instanceof UploadedFileInterface) { - // done! - break; - } - - // For standard SAPI environments, check that the upload - // was valid - if (! is_uploaded_file($content['tmp_name'])) { - $this->throwError($content, self::ATTACK); - } - break; - - case 1: - $this->throwError($content, self::INI_SIZE); - break; - - case 2: - $this->throwError($content, self::FORM_SIZE); - break; - - case 3: - $this->throwError($content, self::PARTIAL); - break; - - case 4: - $this->throwError($content, self::NO_FILE); - break; - - case 6: - $this->throwError($content, self::NO_TMP_DIR); - break; - - case 7: - $this->throwError($content, self::CANT_WRITE); - break; - - case 8: - $this->throwError($content, self::EXTENSION); - break; - - default: - $this->throwError($content, self::UNKNOWN); - break; - } - } - - if ($this->getMessages()) { - return false; - } - - return true; - } - - /** - * Throws an error of the given type - * - * @param array|string|UploadedFileInterface $file - * @param string $errorType - * @return false - */ - protected function throwError($file, $errorType) - { - if ($file !== null) { - if (is_array($file)) { - if (array_key_exists('name', $file)) { - $this->value = $file['name']; - } - } elseif (is_string($file)) { - $this->value = $file; - } elseif ($file instanceof UploadedFileInterface) { - $this->value = $file->getClientFilename(); - } - } - - $this->error($errorType); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/File/UploadFile.php b/lib/laminas/laminas-validator/src/File/UploadFile.php deleted file mode 100644 index 9d73f54af..000000000 --- a/lib/laminas/laminas-validator/src/File/UploadFile.php +++ /dev/null @@ -1,175 +0,0 @@ - 'The uploaded file exceeds the upload_max_filesize directive in php.ini', - self::FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was ' - . 'specified in the HTML form', - self::PARTIAL => 'The uploaded file was only partially uploaded', - self::NO_FILE => 'No file was uploaded', - self::NO_TMP_DIR => 'Missing a temporary folder', - self::CANT_WRITE => 'Failed to write file to disk', - self::EXTENSION => 'A PHP extension stopped the file upload', - self::ATTACK => 'File was illegally uploaded. This could be a possible attack', - self::FILE_NOT_FOUND => 'File was not found', - self::UNKNOWN => 'Unknown error while uploading file', - ]; - - /** - * Returns true if and only if the file was uploaded without errors - * - * @param string|array|UploadedFileInterface $value File to check for upload errors - * @return bool - * @throws Exception\InvalidArgumentException - */ - public function isValid($value) - { - if (is_array($value)) { - if (! isset($value['tmp_name']) || ! isset($value['name']) || ! isset($value['error'])) { - throw new Exception\InvalidArgumentException( - 'Value array must be in $_FILES format' - ); - } - - return $this->validateUploadedFile( - $value['error'], - $value['name'], - $value['tmp_name'] - ); - } - - if ($value instanceof UploadedFileInterface) { - return $this->validatePsr7UploadedFile($value); - } - - if (is_string($value)) { - return $this->validateUploadedFile(0, basename($value), $value); - } - - $this->error(self::UNKNOWN); - return false; - } - - /** - * @param int $error UPLOAD_ERR_* constant value - * @return bool - */ - private function validateFileFromErrorCode($error) - { - switch ($error) { - case UPLOAD_ERR_OK: - return true; - - case UPLOAD_ERR_INI_SIZE: - $this->error(self::INI_SIZE); - return false; - - case UPLOAD_ERR_FORM_SIZE: - $this->error(self::FORM_SIZE); - return false; - - case UPLOAD_ERR_PARTIAL: - $this->error(self::PARTIAL); - return false; - - case UPLOAD_ERR_NO_FILE: - $this->error(self::NO_FILE); - return false; - - case UPLOAD_ERR_NO_TMP_DIR: - $this->error(self::NO_TMP_DIR); - return false; - - case UPLOAD_ERR_CANT_WRITE: - $this->error(self::CANT_WRITE); - return false; - - case UPLOAD_ERR_EXTENSION: - $this->error(self::EXTENSION); - return false; - - default: - $this->error(self::UNKNOWN); - return false; - } - } - - /** - * @param int $error UPLOAD_ERR_* constant - * @param string $filename - * @param string $uploadedFile Name of uploaded file (gen tmp_name) - * @return bool - */ - private function validateUploadedFile($error, $filename, $uploadedFile) - { - $this->setValue($filename); - - // Normal errors can be validated normally - if ($error !== UPLOAD_ERR_OK) { - return $this->validateFileFromErrorCode($error); - } - - // Did we get no name? Is the file missing? - if (empty($uploadedFile) || false === is_file($uploadedFile)) { - $this->error(self::FILE_NOT_FOUND); - return false; - } - - // Do we have an invalid upload? - if (! is_uploaded_file($uploadedFile)) { - $this->error(self::ATTACK); - return false; - } - - return true; - } - - /** - * @return bool - */ - private function validatePsr7UploadedFile(UploadedFileInterface $uploadedFile) - { - $this->setValue($uploadedFile); - return $this->validateFileFromErrorCode($uploadedFile->getError()); - } -} diff --git a/lib/laminas/laminas-validator/src/File/WordCount.php b/lib/laminas/laminas-validator/src/File/WordCount.php deleted file mode 100644 index 107fb6fdd..000000000 --- a/lib/laminas/laminas-validator/src/File/WordCount.php +++ /dev/null @@ -1,204 +0,0 @@ - "Too many words, maximum '%max%' are allowed but '%count%' were counted", - self::TOO_LESS => "Too few words, minimum '%min%' are expected but '%count%' were counted", - self::NOT_FOUND => 'File is not readable or does not exist', - ]; - - /** @var array Error message template variables */ - protected $messageVariables = [ - 'min' => ['options' => 'min'], - 'max' => ['options' => 'max'], - 'count' => 'count', - ]; - - /** - * Word count - * - * @var int - */ - protected $count; - - /** - * Options for this validator - * - * @var array - */ - protected $options = [ - 'min' => null, // Minimum word count, if null there is no minimum word count - 'max' => null, // Maximum word count, if null there is no maximum word count - ]; - - /** - * Sets validator options - * - * Min limits the word count, when used with max=null it is the maximum word count - * It also accepts an array with the keys 'min' and 'max' - * - * If $options is an integer, it will be used as maximum word count - * As Array is accepts the following keys: - * 'min': Minimum word count - * 'max': Maximum word count - * - * @param int|array|Traversable $options Options for the adapter - */ - public function __construct($options = null) - { - if (1 < func_num_args()) { - $args = func_get_args(); - $options = [ - 'min' => array_shift($args), - 'max' => array_shift($args), - ]; - } - - if (is_string($options) || is_numeric($options)) { - $options = ['max' => $options]; - } - - parent::__construct($options); - } - - /** - * Returns the minimum word count - * - * @return int - */ - public function getMin() - { - return $this->options['min']; - } - - /** - * Sets the minimum word count - * - * @param int|array $min The minimum word count - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException When min is greater than max. - */ - public function setMin($min) - { - if (is_array($min) && isset($min['min'])) { - $min = $min['min']; - } - - if (! is_numeric($min)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - $min = (int) $min; - if (($this->getMax() !== null) && ($min > $this->getMax())) { - throw new Exception\InvalidArgumentException( - "The minimum must be less than or equal to the maximum word count, but $min > {$this->getMax()}" - ); - } - - $this->options['min'] = $min; - return $this; - } - - /** - * Returns the maximum word count - * - * @return int - */ - public function getMax() - { - return $this->options['max']; - } - - /** - * Sets the maximum file count - * - * @param int|array $max The maximum word count - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException When max is smaller than min. - */ - public function setMax($max) - { - if (is_array($max) && isset($max['max'])) { - $max = $max['max']; - } - - if (! is_numeric($max)) { - throw new Exception\InvalidArgumentException('Invalid options to validator provided'); - } - - $max = (int) $max; - if (($this->getMin() !== null) && ($max < $this->getMin())) { - throw new Exception\InvalidArgumentException( - "The maximum must be greater than or equal to the minimum word count, but $max < {$this->getMin()}" - ); - } - - $this->options['max'] = $max; - return $this; - } - - /** - * Returns true if and only if the counted words are at least min and - * not bigger than max (when max is not null). - * - * @param string|array $value Filename to check for word count - * @param array $file File data from \Laminas\File\Transfer\Transfer (optional) - * @return bool - */ - public function isValid($value, $file = null) - { - $fileInfo = $this->getFileInfo($value, $file); - - $this->setValue($fileInfo['filename']); - - // Is file readable ? - if (empty($fileInfo['file']) || false === is_readable($fileInfo['file'])) { - $this->error(self::NOT_FOUND); - return false; - } - - $content = file_get_contents($fileInfo['file']); - $this->count = str_word_count($content); - if (($this->getMax() !== null) && ($this->count > $this->getMax())) { - $this->error(self::TOO_MUCH); - return false; - } - - if (($this->getMin() !== null) && ($this->count < $this->getMin())) { - $this->error(self::TOO_LESS); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/GpsPoint.php b/lib/laminas/laminas-validator/src/GpsPoint.php deleted file mode 100644 index 0c7133ba1..000000000 --- a/lib/laminas/laminas-validator/src/GpsPoint.php +++ /dev/null @@ -1,122 +0,0 @@ - '%value% is out of Bounds.', - 'gpsPointConvertError' => '%value% can not converted into a Decimal Degree Value.', - 'gpsPointIncompleteCoordinate' => '%value% did not provided a complete Coordinate', - ]; - - /** - * Returns true if and only if $value meets the validation requirements - * - * If $value fails validation, then this method returns false, and - * getMessages() will return an array of messages that explain why the - * validation failed. - * - * @param mixed $value - * @return bool - * @throws Exception\RuntimeException If validation of $value is impossible. - */ - public function isValid($value) - { - if (! str_contains($value, ',')) { - $this->error(self::INCOMPLETE_COORDINATE, $value); - return false; - } - - [$lat, $long] = explode(',', $value); - - if ($this->isValidCoordinate($lat, 90.0000) && $this->isValidCoordinate($long, 180.000)) { - return true; - } - - return false; - } - - /** - * @param string $value - */ - private function isValidCoordinate($value, float $maxBoundary): bool - { - $this->value = $value; - - $value = $this->removeWhiteSpace($value); - if ($this->isDMSValue($value)) { - $value = $this->convertValue($value); - } else { - $value = $this->removeDegreeSign($value); - } - - if ($value === false || $value === null) { - $this->error(self::CONVERT_ERROR); - return false; - } - - $doubleLatitude = (double) $value; - - if ($doubleLatitude <= $maxBoundary && $doubleLatitude >= $maxBoundary * -1) { - return true; - } - - $this->error(self::OUT_OF_BOUNDS); - return false; - } - - /** - * Determines if the give value is a Degrees Minutes Second Definition - */ - private function isDMSValue(string $value): bool - { - return preg_match('/([°\'"]+[NESW])/', $value) > 0; - } - - /** - * @param string $value - * @return false|float - */ - private function convertValue($value) - { - $matches = []; - $result = preg_match_all('/(\d{1,3})°(\d{1,2})\'(\d{1,2}[\.\d]{0,6})"[NESW]/i', $value, $matches); - - if ($result === false || $result === 0) { - return false; - } - - return $matches[1][0] + $matches[2][0] / 60 + ((double) $matches[3][0]) / 3600; - } - - /** - * @param string $value - * @return string - */ - private function removeWhiteSpace($value) - { - return preg_replace('/\s/', '', $value); - } - - /** - * @param string $value - * @return string - */ - private function removeDegreeSign($value) - { - return str_replace('°', '', $value); - } -} diff --git a/lib/laminas/laminas-validator/src/GreaterThan.php b/lib/laminas/laminas-validator/src/GreaterThan.php deleted file mode 100644 index bc26c81e1..000000000 --- a/lib/laminas/laminas-validator/src/GreaterThan.php +++ /dev/null @@ -1,153 +0,0 @@ - "The input is not greater than '%min%'", - self::NOT_GREATER_INCLUSIVE => "The input is not greater than or equal to '%min%'", - ]; - - /** @var array */ - protected $messageVariables = [ - 'min' => 'min', - ]; - - /** - * Minimum value - * - * @var mixed - */ - protected $min; - - /** - * Whether to do inclusive comparisons, allowing equivalence to max - * - * If false, then strict comparisons are done, and the value may equal - * the min option - * - * @var bool - */ - protected $inclusive; - - /** - * Sets validator options - * - * @param array|Traversable $options - * @throws Exception\InvalidArgumentException - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - if (! is_array($options)) { - $options = func_get_args(); - $temp['min'] = array_shift($options); - - if (! empty($options)) { - $temp['inclusive'] = array_shift($options); - } - - $options = $temp; - } - - if (! array_key_exists('min', $options)) { - throw new Exception\InvalidArgumentException("Missing option 'min'"); - } - - if (! array_key_exists('inclusive', $options)) { - $options['inclusive'] = false; - } - - $this->setMin($options['min']) - ->setInclusive($options['inclusive']); - - parent::__construct($options); - } - - /** - * Returns the min option - * - * @return mixed - */ - public function getMin() - { - return $this->min; - } - - /** - * Sets the min option - * - * @return $this Provides a fluent interface - */ - public function setMin(mixed $min) - { - $this->min = $min; - return $this; - } - - /** - * Returns the inclusive option - * - * @return bool - */ - public function getInclusive() - { - return $this->inclusive; - } - - /** - * Sets the inclusive option - * - * @param bool $inclusive - * @return $this Provides a fluent interface - */ - public function setInclusive($inclusive) - { - $this->inclusive = $inclusive; - return $this; - } - - /** - * Returns true if and only if $value is greater than min option - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - $this->setValue($value); - - if ($this->inclusive) { - if ($this->min > $value) { - $this->error(self::NOT_GREATER_INCLUSIVE); - return false; - } - } else { - if ($this->min >= $value) { - $this->error(self::NOT_GREATER); - return false; - } - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Hex.php b/lib/laminas/laminas-validator/src/Hex.php deleted file mode 100644 index b00198578..000000000 --- a/lib/laminas/laminas-validator/src/Hex.php +++ /dev/null @@ -1,45 +0,0 @@ - 'Invalid type given. String expected', - self::NOT_HEX => 'The input contains non-hexadecimal characters', - ]; - - /** - * Returns true if and only if $value contains only hexadecimal digit characters - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value) && ! is_int($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - if (! ctype_xdigit((string) $value)) { - $this->error(self::NOT_HEX); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Hostname.php b/lib/laminas/laminas-validator/src/Hostname.php deleted file mode 100644 index bc3d0559f..000000000 --- a/lib/laminas/laminas-validator/src/Hostname.php +++ /dev/null @@ -1,2295 +0,0 @@ - "The input appears to be a DNS hostname but the given punycode notation cannot be decoded", - self::INVALID => "Invalid type given. String expected", - self::INVALID_DASH => "The input appears to be a DNS hostname but contains a dash in an invalid position", - self::INVALID_HOSTNAME => "The input does not match the expected structure for a DNS hostname", - self::INVALID_HOSTNAME_SCHEMA => "The input appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", - self::INVALID_LOCAL_NAME => "The input does not appear to be a valid local network name", - self::INVALID_URI => "The input does not appear to be a valid URI hostname", - self::IP_ADDRESS_NOT_ALLOWED => "The input appears to be an IP address, but IP addresses are not allowed", - self::LOCAL_NAME_NOT_ALLOWED => "The input appears to be a local network name but local network names are not allowed", - self::UNDECIPHERABLE_TLD => "The input appears to be a DNS hostname but cannot extract TLD part", - self::UNKNOWN_TLD => "The input appears to be a DNS hostname but cannot match TLD against known list", - ]; - - /** @var array */ - protected $messageVariables = [ - 'tld' => 'tld', - ]; - - public const ALLOW_DNS = 1; // Allows Internet domain names (e.g., example.com) - public const ALLOW_IP = 2; // Allows IP addresses - public const ALLOW_LOCAL = 4; // Allows local network names (e.g., localhost, www.localdomain) - public const ALLOW_URI = 8; // Allows URI hostnames - public const ALLOW_ALL = 15; // Allows all types of hostnames - - /** - * Array of valid top-level-domains - * IanaVersion 2022072400 - * - * @see ftp://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain - * @see http://www.iana.org/domains/root/db/ Official list of supported TLDs - * - * @var string[] - */ - protected $validTlds = [ - 'aaa', - 'aarp', - 'abarth', - 'abb', - 'abbott', - 'abbvie', - 'abc', - 'able', - 'abogado', - 'abudhabi', - 'ac', - 'academy', - 'accenture', - 'accountant', - 'accountants', - 'aco', - 'actor', - 'ad', - 'adac', - 'ads', - 'adult', - 'ae', - 'aeg', - 'aero', - 'aetna', - 'af', - 'afl', - 'africa', - 'ag', - 'agakhan', - 'agency', - 'ai', - 'aig', - 'airbus', - 'airforce', - 'airtel', - 'akdn', - 'al', - 'alfaromeo', - 'alibaba', - 'alipay', - 'allfinanz', - 'allstate', - 'ally', - 'alsace', - 'alstom', - 'am', - 'amazon', - 'americanexpress', - 'americanfamily', - 'amex', - 'amfam', - 'amica', - 'amsterdam', - 'analytics', - 'android', - 'anquan', - 'anz', - 'ao', - 'aol', - 'apartments', - 'app', - 'apple', - 'aq', - 'aquarelle', - 'ar', - 'arab', - 'aramco', - 'archi', - 'army', - 'arpa', - 'art', - 'arte', - 'as', - 'asda', - 'asia', - 'associates', - 'at', - 'athleta', - 'attorney', - 'au', - 'auction', - 'audi', - 'audible', - 'audio', - 'auspost', - 'author', - 'auto', - 'autos', - 'avianca', - 'aw', - 'aws', - 'ax', - 'axa', - 'az', - 'azure', - 'ba', - 'baby', - 'baidu', - 'banamex', - 'bananarepublic', - 'band', - 'bank', - 'bar', - 'barcelona', - 'barclaycard', - 'barclays', - 'barefoot', - 'bargains', - 'baseball', - 'basketball', - 'bauhaus', - 'bayern', - 'bb', - 'bbc', - 'bbt', - 'bbva', - 'bcg', - 'bcn', - 'bd', - 'be', - 'beats', - 'beauty', - 'beer', - 'bentley', - 'berlin', - 'best', - 'bestbuy', - 'bet', - 'bf', - 'bg', - 'bh', - 'bharti', - 'bi', - 'bible', - 'bid', - 'bike', - 'bing', - 'bingo', - 'bio', - 'biz', - 'bj', - 'black', - 'blackfriday', - 'blockbuster', - 'blog', - 'bloomberg', - 'blue', - 'bm', - 'bms', - 'bmw', - 'bn', - 'bnpparibas', - 'bo', - 'boats', - 'boehringer', - 'bofa', - 'bom', - 'bond', - 'boo', - 'book', - 'booking', - 'bosch', - 'bostik', - 'boston', - 'bot', - 'boutique', - 'box', - 'br', - 'bradesco', - 'bridgestone', - 'broadway', - 'broker', - 'brother', - 'brussels', - 'bs', - 'bt', - 'bugatti', - 'build', - 'builders', - 'business', - 'buy', - 'buzz', - 'bv', - 'bw', - 'by', - 'bz', - 'bzh', - 'ca', - 'cab', - 'cafe', - 'cal', - 'call', - 'calvinklein', - 'cam', - 'camera', - 'camp', - 'cancerresearch', - 'canon', - 'capetown', - 'capital', - 'capitalone', - 'car', - 'caravan', - 'cards', - 'care', - 'career', - 'careers', - 'cars', - 'casa', - 'case', - 'cash', - 'casino', - 'cat', - 'catering', - 'catholic', - 'cba', - 'cbn', - 'cbre', - 'cbs', - 'cc', - 'cd', - 'center', - 'ceo', - 'cern', - 'cf', - 'cfa', - 'cfd', - 'cg', - 'ch', - 'chanel', - 'channel', - 'charity', - 'chase', - 'chat', - 'cheap', - 'chintai', - 'christmas', - 'chrome', - 'church', - 'ci', - 'cipriani', - 'circle', - 'cisco', - 'citadel', - 'citi', - 'citic', - 'city', - 'cityeats', - 'ck', - 'cl', - 'claims', - 'cleaning', - 'click', - 'clinic', - 'clinique', - 'clothing', - 'cloud', - 'club', - 'clubmed', - 'cm', - 'cn', - 'co', - 'coach', - 'codes', - 'coffee', - 'college', - 'cologne', - 'com', - 'comcast', - 'commbank', - 'community', - 'company', - 'compare', - 'computer', - 'comsec', - 'condos', - 'construction', - 'consulting', - 'contact', - 'contractors', - 'cooking', - 'cookingchannel', - 'cool', - 'coop', - 'corsica', - 'country', - 'coupon', - 'coupons', - 'courses', - 'cpa', - 'cr', - 'credit', - 'creditcard', - 'creditunion', - 'cricket', - 'crown', - 'crs', - 'cruise', - 'cruises', - 'cu', - 'cuisinella', - 'cv', - 'cw', - 'cx', - 'cy', - 'cymru', - 'cyou', - 'cz', - 'dabur', - 'dad', - 'dance', - 'data', - 'date', - 'dating', - 'datsun', - 'day', - 'dclk', - 'dds', - 'de', - 'deal', - 'dealer', - 'deals', - 'degree', - 'delivery', - 'dell', - 'deloitte', - 'delta', - 'democrat', - 'dental', - 'dentist', - 'desi', - 'design', - 'dev', - 'dhl', - 'diamonds', - 'diet', - 'digital', - 'direct', - 'directory', - 'discount', - 'discover', - 'dish', - 'diy', - 'dj', - 'dk', - 'dm', - 'dnp', - 'do', - 'docs', - 'doctor', - 'dog', - 'domains', - 'dot', - 'download', - 'drive', - 'dtv', - 'dubai', - 'dunlop', - 'dupont', - 'durban', - 'dvag', - 'dvr', - 'dz', - 'earth', - 'eat', - 'ec', - 'eco', - 'edeka', - 'edu', - 'education', - 'ee', - 'eg', - 'email', - 'emerck', - 'energy', - 'engineer', - 'engineering', - 'enterprises', - 'epson', - 'equipment', - 'er', - 'ericsson', - 'erni', - 'es', - 'esq', - 'estate', - 'et', - 'etisalat', - 'eu', - 'eurovision', - 'eus', - 'events', - 'exchange', - 'expert', - 'exposed', - 'express', - 'extraspace', - 'fage', - 'fail', - 'fairwinds', - 'faith', - 'family', - 'fan', - 'fans', - 'farm', - 'farmers', - 'fashion', - 'fast', - 'fedex', - 'feedback', - 'ferrari', - 'ferrero', - 'fi', - 'fiat', - 'fidelity', - 'fido', - 'film', - 'final', - 'finance', - 'financial', - 'fire', - 'firestone', - 'firmdale', - 'fish', - 'fishing', - 'fit', - 'fitness', - 'fj', - 'fk', - 'flickr', - 'flights', - 'flir', - 'florist', - 'flowers', - 'fly', - 'fm', - 'fo', - 'foo', - 'food', - 'foodnetwork', - 'football', - 'ford', - 'forex', - 'forsale', - 'forum', - 'foundation', - 'fox', - 'fr', - 'free', - 'fresenius', - 'frl', - 'frogans', - 'frontdoor', - 'frontier', - 'ftr', - 'fujitsu', - 'fun', - 'fund', - 'furniture', - 'futbol', - 'fyi', - 'ga', - 'gal', - 'gallery', - 'gallo', - 'gallup', - 'game', - 'games', - 'gap', - 'garden', - 'gay', - 'gb', - 'gbiz', - 'gd', - 'gdn', - 'ge', - 'gea', - 'gent', - 'genting', - 'george', - 'gf', - 'gg', - 'ggee', - 'gh', - 'gi', - 'gift', - 'gifts', - 'gives', - 'giving', - 'gl', - 'glass', - 'gle', - 'global', - 'globo', - 'gm', - 'gmail', - 'gmbh', - 'gmo', - 'gmx', - 'gn', - 'godaddy', - 'gold', - 'goldpoint', - 'golf', - 'goo', - 'goodyear', - 'goog', - 'google', - 'gop', - 'got', - 'gov', - 'gp', - 'gq', - 'gr', - 'grainger', - 'graphics', - 'gratis', - 'green', - 'gripe', - 'grocery', - 'group', - 'gs', - 'gt', - 'gu', - 'guardian', - 'gucci', - 'guge', - 'guide', - 'guitars', - 'guru', - 'gw', - 'gy', - 'hair', - 'hamburg', - 'hangout', - 'haus', - 'hbo', - 'hdfc', - 'hdfcbank', - 'health', - 'healthcare', - 'help', - 'helsinki', - 'here', - 'hermes', - 'hgtv', - 'hiphop', - 'hisamitsu', - 'hitachi', - 'hiv', - 'hk', - 'hkt', - 'hm', - 'hn', - 'hockey', - 'holdings', - 'holiday', - 'homedepot', - 'homegoods', - 'homes', - 'homesense', - 'honda', - 'horse', - 'hospital', - 'host', - 'hosting', - 'hot', - 'hoteles', - 'hotels', - 'hotmail', - 'house', - 'how', - 'hr', - 'hsbc', - 'ht', - 'hu', - 'hughes', - 'hyatt', - 'hyundai', - 'ibm', - 'icbc', - 'ice', - 'icu', - 'id', - 'ie', - 'ieee', - 'ifm', - 'ikano', - 'il', - 'im', - 'imamat', - 'imdb', - 'immo', - 'immobilien', - 'in', - 'inc', - 'industries', - 'infiniti', - 'info', - 'ing', - 'ink', - 'institute', - 'insurance', - 'insure', - 'int', - 'international', - 'intuit', - 'investments', - 'io', - 'ipiranga', - 'iq', - 'ir', - 'irish', - 'is', - 'ismaili', - 'ist', - 'istanbul', - 'it', - 'itau', - 'itv', - 'jaguar', - 'java', - 'jcb', - 'je', - 'jeep', - 'jetzt', - 'jewelry', - 'jio', - 'jll', - 'jm', - 'jmp', - 'jnj', - 'jo', - 'jobs', - 'joburg', - 'jot', - 'joy', - 'jp', - 'jpmorgan', - 'jprs', - 'juegos', - 'juniper', - 'kaufen', - 'kddi', - 'ke', - 'kerryhotels', - 'kerrylogistics', - 'kerryproperties', - 'kfh', - 'kg', - 'kh', - 'ki', - 'kia', - 'kids', - 'kim', - 'kinder', - 'kindle', - 'kitchen', - 'kiwi', - 'km', - 'kn', - 'koeln', - 'komatsu', - 'kosher', - 'kp', - 'kpmg', - 'kpn', - 'kr', - 'krd', - 'kred', - 'kuokgroup', - 'kw', - 'ky', - 'kyoto', - 'kz', - 'la', - 'lacaixa', - 'lamborghini', - 'lamer', - 'lancaster', - 'lancia', - 'land', - 'landrover', - 'lanxess', - 'lasalle', - 'lat', - 'latino', - 'latrobe', - 'law', - 'lawyer', - 'lb', - 'lc', - 'lds', - 'lease', - 'leclerc', - 'lefrak', - 'legal', - 'lego', - 'lexus', - 'lgbt', - 'li', - 'lidl', - 'life', - 'lifeinsurance', - 'lifestyle', - 'lighting', - 'like', - 'lilly', - 'limited', - 'limo', - 'lincoln', - 'linde', - 'link', - 'lipsy', - 'live', - 'living', - 'lk', - 'llc', - 'llp', - 'loan', - 'loans', - 'locker', - 'locus', - 'loft', - 'lol', - 'london', - 'lotte', - 'lotto', - 'love', - 'lpl', - 'lplfinancial', - 'lr', - 'ls', - 'lt', - 'ltd', - 'ltda', - 'lu', - 'lundbeck', - 'luxe', - 'luxury', - 'lv', - 'ly', - 'ma', - 'macys', - 'madrid', - 'maif', - 'maison', - 'makeup', - 'man', - 'management', - 'mango', - 'map', - 'market', - 'marketing', - 'markets', - 'marriott', - 'marshalls', - 'maserati', - 'mattel', - 'mba', - 'mc', - 'mckinsey', - 'md', - 'me', - 'med', - 'media', - 'meet', - 'melbourne', - 'meme', - 'memorial', - 'men', - 'menu', - 'merckmsd', - 'mg', - 'mh', - 'miami', - 'microsoft', - 'mil', - 'mini', - 'mint', - 'mit', - 'mitsubishi', - 'mk', - 'ml', - 'mlb', - 'mls', - 'mm', - 'mma', - 'mn', - 'mo', - 'mobi', - 'mobile', - 'moda', - 'moe', - 'moi', - 'mom', - 'monash', - 'money', - 'monster', - 'mormon', - 'mortgage', - 'moscow', - 'moto', - 'motorcycles', - 'mov', - 'movie', - 'mp', - 'mq', - 'mr', - 'ms', - 'msd', - 'mt', - 'mtn', - 'mtr', - 'mu', - 'museum', - 'music', - 'mutual', - 'mv', - 'mw', - 'mx', - 'my', - 'mz', - 'na', - 'nab', - 'nagoya', - 'name', - 'natura', - 'navy', - 'nba', - 'nc', - 'ne', - 'nec', - 'net', - 'netbank', - 'netflix', - 'network', - 'neustar', - 'new', - 'news', - 'next', - 'nextdirect', - 'nexus', - 'nf', - 'nfl', - 'ng', - 'ngo', - 'nhk', - 'ni', - 'nico', - 'nike', - 'nikon', - 'ninja', - 'nissan', - 'nissay', - 'nl', - 'no', - 'nokia', - 'northwesternmutual', - 'norton', - 'now', - 'nowruz', - 'nowtv', - 'np', - 'nr', - 'nra', - 'nrw', - 'ntt', - 'nu', - 'nyc', - 'nz', - 'obi', - 'observer', - 'office', - 'okinawa', - 'olayan', - 'olayangroup', - 'oldnavy', - 'ollo', - 'om', - 'omega', - 'one', - 'ong', - 'onl', - 'online', - 'ooo', - 'open', - 'oracle', - 'orange', - 'org', - 'organic', - 'origins', - 'osaka', - 'otsuka', - 'ott', - 'ovh', - 'pa', - 'page', - 'panasonic', - 'paris', - 'pars', - 'partners', - 'parts', - 'party', - 'passagens', - 'pay', - 'pccw', - 'pe', - 'pet', - 'pf', - 'pfizer', - 'pg', - 'ph', - 'pharmacy', - 'phd', - 'philips', - 'phone', - 'photo', - 'photography', - 'photos', - 'physio', - 'pics', - 'pictet', - 'pictures', - 'pid', - 'pin', - 'ping', - 'pink', - 'pioneer', - 'pizza', - 'pk', - 'pl', - 'place', - 'play', - 'playstation', - 'plumbing', - 'plus', - 'pm', - 'pn', - 'pnc', - 'pohl', - 'poker', - 'politie', - 'porn', - 'post', - 'pr', - 'pramerica', - 'praxi', - 'press', - 'prime', - 'pro', - 'prod', - 'productions', - 'prof', - 'progressive', - 'promo', - 'properties', - 'property', - 'protection', - 'pru', - 'prudential', - 'ps', - 'pt', - 'pub', - 'pw', - 'pwc', - 'py', - 'qa', - 'qpon', - 'quebec', - 'quest', - 'racing', - 'radio', - 're', - 'read', - 'realestate', - 'realtor', - 'realty', - 'recipes', - 'red', - 'redstone', - 'redumbrella', - 'rehab', - 'reise', - 'reisen', - 'reit', - 'reliance', - 'ren', - 'rent', - 'rentals', - 'repair', - 'report', - 'republican', - 'rest', - 'restaurant', - 'review', - 'reviews', - 'rexroth', - 'rich', - 'richardli', - 'ricoh', - 'ril', - 'rio', - 'rip', - 'ro', - 'rocher', - 'rocks', - 'rodeo', - 'rogers', - 'room', - 'rs', - 'rsvp', - 'ru', - 'rugby', - 'ruhr', - 'run', - 'rw', - 'rwe', - 'ryukyu', - 'sa', - 'saarland', - 'safe', - 'safety', - 'sakura', - 'sale', - 'salon', - 'samsclub', - 'samsung', - 'sandvik', - 'sandvikcoromant', - 'sanofi', - 'sap', - 'sarl', - 'sas', - 'save', - 'saxo', - 'sb', - 'sbi', - 'sbs', - 'sc', - 'sca', - 'scb', - 'schaeffler', - 'schmidt', - 'scholarships', - 'school', - 'schule', - 'schwarz', - 'science', - 'scot', - 'sd', - 'se', - 'search', - 'seat', - 'secure', - 'security', - 'seek', - 'select', - 'sener', - 'services', - 'ses', - 'seven', - 'sew', - 'sex', - 'sexy', - 'sfr', - 'sg', - 'sh', - 'shangrila', - 'sharp', - 'shaw', - 'shell', - 'shia', - 'shiksha', - 'shoes', - 'shop', - 'shopping', - 'shouji', - 'show', - 'showtime', - 'si', - 'silk', - 'sina', - 'singles', - 'site', - 'sj', - 'sk', - 'ski', - 'skin', - 'sky', - 'skype', - 'sl', - 'sling', - 'sm', - 'smart', - 'smile', - 'sn', - 'sncf', - 'so', - 'soccer', - 'social', - 'softbank', - 'software', - 'sohu', - 'solar', - 'solutions', - 'song', - 'sony', - 'soy', - 'spa', - 'space', - 'sport', - 'spot', - 'sr', - 'srl', - 'ss', - 'st', - 'stada', - 'staples', - 'star', - 'statebank', - 'statefarm', - 'stc', - 'stcgroup', - 'stockholm', - 'storage', - 'store', - 'stream', - 'studio', - 'study', - 'style', - 'su', - 'sucks', - 'supplies', - 'supply', - 'support', - 'surf', - 'surgery', - 'suzuki', - 'sv', - 'swatch', - 'swiss', - 'sx', - 'sy', - 'sydney', - 'systems', - 'sz', - 'tab', - 'taipei', - 'talk', - 'taobao', - 'target', - 'tatamotors', - 'tatar', - 'tattoo', - 'tax', - 'taxi', - 'tc', - 'tci', - 'td', - 'tdk', - 'team', - 'tech', - 'technology', - 'tel', - 'temasek', - 'tennis', - 'teva', - 'tf', - 'tg', - 'th', - 'thd', - 'theater', - 'theatre', - 'tiaa', - 'tickets', - 'tienda', - 'tiffany', - 'tips', - 'tires', - 'tirol', - 'tj', - 'tjmaxx', - 'tjx', - 'tk', - 'tkmaxx', - 'tl', - 'tm', - 'tmall', - 'tn', - 'to', - 'today', - 'tokyo', - 'tools', - 'top', - 'toray', - 'toshiba', - 'total', - 'tours', - 'town', - 'toyota', - 'toys', - 'tr', - 'trade', - 'trading', - 'training', - 'travel', - 'travelchannel', - 'travelers', - 'travelersinsurance', - 'trust', - 'trv', - 'tt', - 'tube', - 'tui', - 'tunes', - 'tushu', - 'tv', - 'tvs', - 'tw', - 'tz', - 'ua', - 'ubank', - 'ubs', - 'ug', - 'uk', - 'unicom', - 'university', - 'uno', - 'uol', - 'ups', - 'us', - 'uy', - 'uz', - 'va', - 'vacations', - 'vana', - 'vanguard', - 'vc', - 've', - 'vegas', - 'ventures', - 'verisign', - 'versicherung', - 'vet', - 'vg', - 'vi', - 'viajes', - 'video', - 'vig', - 'viking', - 'villas', - 'vin', - 'vip', - 'virgin', - 'visa', - 'vision', - 'viva', - 'vivo', - 'vlaanderen', - 'vn', - 'vodka', - 'volkswagen', - 'volvo', - 'vote', - 'voting', - 'voto', - 'voyage', - 'vu', - 'vuelos', - 'wales', - 'walmart', - 'walter', - 'wang', - 'wanggou', - 'watch', - 'watches', - 'weather', - 'weatherchannel', - 'webcam', - 'weber', - 'website', - 'wed', - 'wedding', - 'weibo', - 'weir', - 'wf', - 'whoswho', - 'wien', - 'wiki', - 'williamhill', - 'win', - 'windows', - 'wine', - 'winners', - 'wme', - 'wolterskluwer', - 'woodside', - 'work', - 'works', - 'world', - 'wow', - 'ws', - 'wtc', - 'wtf', - 'xbox', - 'xerox', - 'xfinity', - 'xihuan', - 'xin', - 'कॉम', - 'セール', - '佛山', - 'ಭಾರತ', - '慈善', - '集团', - '在线', - '한국', - 'ଭାରତ', - '点看', - 'คอม', - 'ভাৰত', - 'ভারত', - '八卦', - 'ישראל', - 'موقع', - 'বাংলা', - '公益', - '公司', - '香格里拉', - '网站', - '移动', - '我爱你', - 'москва', - 'қаз', - 'католик', - 'онлайн', - 'сайт', - '联通', - 'срб', - 'бг', - 'бел', - 'קום', - '时尚', - '微博', - '淡马锡', - 'ファッション', - 'орг', - 'नेट', - 'ストア', - 'アマゾン', - '삼성', - 'சிங்கப்பூர்', - '商标', - '商店', - '商城', - 'дети', - 'мкд', - 'ею', - 'ポイント', - '新闻', - '家電', - 'كوم', - '中文网', - '中信', - '中国', - '中國', - '娱乐', - '谷歌', - 'భారత్', - 'ලංකා', - '電訊盈科', - '购物', - 'クラウド', - 'ભારત', - '通販', - 'भारतम्', - 'भारत', - 'भारोत', - '网店', - 'संगठन', - '餐厅', - '网络', - 'ком', - 'укр', - '香港', - '亚马逊', - '诺基亚', - '食品', - '飞利浦', - '台湾', - '台灣', - '手机', - 'мон', - 'الجزائر', - 'عمان', - 'ارامكو', - 'ایران', - 'العليان', - 'اتصالات', - 'امارات', - 'بازار', - 'موريتانيا', - 'پاکستان', - 'الاردن', - 'بارت', - 'بھارت', - 'المغرب', - 'ابوظبي', - 'البحرين', - 'السعودية', - 'ڀارت', - 'كاثوليك', - 'سودان', - 'همراه', - 'عراق', - 'مليسيا', - '澳門', - '닷컴', - '政府', - 'شبكة', - 'بيتك', - 'عرب', - 'გე', - '机构', - '组织机构', - '健康', - 'ไทย', - 'سورية', - '招聘', - 'рус', - 'рф', - 'تونس', - '大拿', - 'ລາວ', - 'みんな', - 'グーグル', - 'ευ', - 'ελ', - '世界', - '書籍', - 'ഭാരതം', - 'ਭਾਰਤ', - '网址', - '닷넷', - 'コム', - '天主教', - '游戏', - 'vermögensberater', - 'vermögensberatung', - '企业', - '信息', - '嘉里大酒店', - '嘉里', - 'مصر', - 'قطر', - '广东', - 'இலங்கை', - 'இந்தியா', - 'հայ', - '新加坡', - 'فلسطين', - '政务', - 'xxx', - 'xyz', - 'yachts', - 'yahoo', - 'yamaxun', - 'yandex', - 'ye', - 'yodobashi', - 'yoga', - 'yokohama', - 'you', - 'youtube', - 'yt', - 'yun', - 'za', - 'zappos', - 'zara', - 'zero', - 'zip', - 'zm', - 'zone', - 'zuerich', - 'zw', - ]; - - /** - * Array for valid Idns - * - * @see http://www.iana.org/domains/idn-tables/ Official list of supported IDN Chars - * (.AC) Ascension Island http://www.nic.ac/pdf/AC-IDN-Policy.pdf - * (.AR) Argentina http://www.nic.ar/faqidn.html - * (.AS) American Samoa http://www.nic.as/idn/chars.cfm - * (.AT) Austria http://www.nic.at/en/service/technical_information/idn/charset_converter/ - * (.BIZ) International http://www.iana.org/domains/idn-tables/ - * (.BR) Brazil http://registro.br/faq/faq6.html - * (.BV) Bouvett Island http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.CAT) Catalan http://www.iana.org/domains/idn-tables/tables/cat_ca_1.0.html - * (.CH) Switzerland https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 - * (.CL) Chile http://www.iana.org/domains/idn-tables/tables/cl_latn_1.0.html - * (.COM) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html - * (.DE) Germany https://www.denic.de/en/know-how/idn-domains/idn-character-list/ - * (.DK) Danmark http://www.dk-hostmaster.dk/index.php?id=151 - * (.EE) Estonia https://www.iana.org/domains/idn-tables/tables/pl_et-pl_1.0.html - * (.ES) Spain https://www.nic.es/media/2008-05/1210147705287.pdf - * (.FI) Finland http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html - * (.GR) Greece https://grweb.ics.forth.gr/CharacterTable1_en.jsp - * (.HR) Croatia https://www.dns.hr/en/portal/files/Odluka-1,2alfanum-dijak.pdf - * (.HU) Hungary http://www.domain.hu/domain/English/szabalyzat/szabalyzat.html - * (.IL) Israel http://www.isoc.org.il/domains/il-domain-rules.html - * (.INFO) International http://www.nic.info/info/idn - * (.IO) British Indian Ocean Territory http://www.nic.io/IO-IDN-Policy.pdf - * (.IR) Iran http://www.nic.ir/Allowable_Characters_dot-iran - * (.IS) Iceland https://www.isnic.is/en/domain/rules#2 - * (.KR) Korea http://www.iana.org/domains/idn-tables/tables/kr_ko-kr_1.0.html - * (.LI) Liechtenstein https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 - * (.LT) Lithuania http://www.domreg.lt/static/doc/public/idn_symbols-en.pdf - * (.MD) Moldova http://www.register.md/ - * (.MUSEUM) International http://www.iana.org/domains/idn-tables/tables/museum_latn_1.0.html - * (.NET) International http://www.verisign.com/information-services/naming-services/internationalized-domain-names/index.html - * (.NO) Norway http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.NU) Niue http://www.worldnames.net/ - * (.ORG) International http://www.pir.org/index.php?db=content/FAQs&tbl=FAQs_Registrant&id=2 - * (.PE) Peru https://www.nic.pe/nuevas_politicas_faq_2.php - * (.PL) Poland http://www.dns.pl/IDN/allowed_character_sets.pdf - * (.PR) Puerto Rico http://www.nic.pr/idn_rules.asp - * (.PT) Portugal https://online.dns.pt/dns_2008/do?com=DS;8216320233;111;+PAGE(4000058)+K-CAT-CODIGO(C.125)+RCNT(100); - * (.RU) Russia http://www.iana.org/domains/idn-tables/tables/ru_ru-ru_1.0.html - * (.SA) Saudi Arabia http://www.iana.org/domains/idn-tables/tables/sa_ar_1.0.html - * (.SE) Sweden http://www.iis.se/english/IDN_campaignsite.shtml?lang=en - * (.SH) Saint Helena http://www.nic.sh/SH-IDN-Policy.pdf - * (.SJ) Svalbard and Jan Mayen http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html - * (.TH) Thailand http://www.iana.org/domains/idn-tables/tables/th_th-th_1.0.html - * (.TM) Turkmenistan http://www.nic.tm/TM-IDN-Policy.pdf - * (.TR) Turkey https://www.nic.tr/index.php - * (.UA) Ukraine http://www.iana.org/domains/idn-tables/tables/ua_cyrl_1.2.html - * (.VE) Venice http://www.iana.org/domains/idn-tables/tables/ve_es_1.0.html - * (.VN) Vietnam http://www.vnnic.vn/english/5-6-300-2-2-04-20071115.htm#1.%20Introduction - * - * @var array> - */ - protected $validIdns = [ - 'AC' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'], - 'AR' => [1 => '/^[\x{002d}0-9a-zà-ãç-êìíñ-õü]{1,63}$/iu'], - 'AS' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$/iu'], - 'AT' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿœšž]{1,63}$/iu'], - 'BIZ' => 'Hostname/Biz.php', - 'BR' => [1 => '/^[\x{002d}0-9a-zà-ãçéíó-õúü]{1,63}$/iu'], - 'BV' => [1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'], - 'CAT' => [1 => '/^[\x{002d}0-9a-z·àç-éíïòóúü]{1,63}$/iu'], - 'CH' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'], - 'CL' => [1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu'], - 'CN' => 'Hostname/Cn.php', - 'COM' => 'Hostname/Com.php', - 'DE' => [1 => '/^[\x{002d}0-9a-záàăâåäãąāæćĉčċçďđéèĕêěëėęēğĝġģĥħíìĭîïĩįīıĵķĺľļłńňñņŋóòŏôöőõøōœĸŕřŗśŝšşßťţŧúùŭûůüűũųūŵýŷÿźžżðþ]{1,63}$/iu'], - 'DK' => [1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu'], - 'EE' => [1 => '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu'], - 'ES' => [1 => '/^[\x{002d}0-9a-zàáçèéíïñòóúü·]{1,63}$/iu'], - 'EU' => [ - 1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu', - 4 => '/^[\x{002d}0-9a-zΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-zἀ-ἇἐ-ἕἠ-ἧἰ-ἷὀ-ὅὐ-ὗὠ-ὧὰ-ὼώᾀ-ᾇᾐ-ᾗᾠ-ᾧᾰ-ᾴᾶᾷῂῃῄῆῇῐ-ῒΐῖῗῠ-ῧῲῳῴῶῷ]{1,63}$/iu', - ], - 'FI' => [1 => '/^[\x{002d}0-9a-zäåö]{1,63}$/iu'], - 'GR' => [1 => '/^[\x{002d}0-9a-zΆΈΉΊΌΎ-ΡΣ-ώἀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼῂῃῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲῳῴῶ-ῼ]{1,63}$/iu'], - 'HK' => 'Hostname/Cn.php', - 'HR' => [1 => '/^[\x{002d}0-9a-zžćčđš]{1,63}$/iu'], - 'HU' => [1 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu'], - 'IL' => [ - 1 => '/^[\x{002d}0-9\x{05D0}-\x{05EA}]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-z]{1,63}$/i', - ], - 'INFO' => [ - 1 => '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', - 4 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', - 5 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 8 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - ], - 'IO' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'], - 'IS' => [1 => '/^[\x{002d}0-9a-záéýúíóþæöð]{1,63}$/iu'], - 'IT' => [1 => '/^[\x{002d}0-9a-zàâäèéêëìîïòôöùûüæœçÿß-]{1,63}$/iu'], - 'JP' => 'Hostname/Jp.php', - 'KR' => [1 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu'], - 'LI' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿœ]{1,63}$/iu'], - 'LT' => [1 => '/^[\x{002d}0-9ąčęėįšųūž]{1,63}$/iu'], - 'MD' => [1 => '/^[\x{002d}0-9ăâîşţ]{1,63}$/iu'], - 'MUSEUM' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćċčďđēėęěğġģħīįıķĺļľłńņňŋōőœŕŗřśşšţťŧūůűųŵŷźżžǎǐǒǔ\x{01E5}\x{01E7}\x{01E9}\x{01EF}ə\x{0292}ẁẃẅỳ]{1,63}$/iu'], - 'NET' => 'Hostname/Com.php', - 'NO' => [1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'], - 'NU' => 'Hostname/Com.php', - 'ORG' => [ - 1 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', - 4 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 6 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', - 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - ], - 'PE' => [1 => '/^[\x{002d}0-9a-zñáéíóúü]{1,63}$/iu'], - 'PL' => [ - 1 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - 2 => '/^[\x{002d}а-ик-ш\x{0450}ѓѕјљњќџ]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', - 4 => '/^[\x{002d}0-9а-яё\x{04C2}]{1,63}$/iu', - 5 => '/^[\x{002d}0-9a-zàáâèéêìíîòóôùúûċġħż]{1,63}$/iu', - 6 => '/^[\x{002d}0-9a-zàäåæéêòóôöøü]{1,63}$/iu', - 7 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 8 => '/^[\x{002d}0-9a-zàáâãçéêíòóôõúü]{1,63}$/iu', - 9 => '/^[\x{002d}0-9a-zâîăşţ]{1,63}$/iu', - 10 => '/^[\x{002d}0-9a-záäéíóôúýčďĺľňŕšťž]{1,63}$/iu', - 11 => '/^[\x{002d}0-9a-zçë]{1,63}$/iu', - 12 => '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu', - 13 => '/^[\x{002d}0-9a-zćčđšž]{1,63}$/iu', - 14 => '/^[\x{002d}0-9a-zâçöûüğış]{1,63}$/iu', - 15 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - 16 => '/^[\x{002d}0-9a-zäõöüšž]{1,63}$/iu', - 17 => '/^[\x{002d}0-9a-zĉĝĥĵŝŭ]{1,63}$/iu', - 18 => '/^[\x{002d}0-9a-zâäéëîô]{1,63}$/iu', - 19 => '/^[\x{002d}0-9a-zàáâäåæçèéêëìíîïðñòôöøùúûüýćčłńřśš]{1,63}$/iu', - 20 => '/^[\x{002d}0-9a-zäåæõöøüšž]{1,63}$/iu', - 21 => '/^[\x{002d}0-9a-zàáçèéìíòóùú]{1,63}$/iu', - 22 => '/^[\x{002d}0-9a-zàáéíóöúüőű]{1,63}$/iu', - 23 => '/^[\x{002d}0-9ΐά-ώ]{1,63}$/iu', - 24 => '/^[\x{002d}0-9a-zàáâåæçèéêëðóôöøüþœ]{1,63}$/iu', - 25 => '/^[\x{002d}0-9a-záäéíóöúüýčďěňřšťůž]{1,63}$/iu', - 26 => '/^[\x{002d}0-9a-z·àçèéíïòóúü]{1,63}$/iu', - 27 => '/^[\x{002d}0-9а-ъьюя\x{0450}\x{045D}]{1,63}$/iu', - 28 => '/^[\x{002d}0-9а-яёіў]{1,63}$/iu', - 29 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 30 => '/^[\x{002d}0-9a-záäåæéëíðóöøúüýþ]{1,63}$/iu', - 31 => '/^[\x{002d}0-9a-zàâæçèéêëîïñôùûüÿœ]{1,63}$/iu', - 32 => '/^[\x{002d}0-9а-щъыьэюяёєіїґ]{1,63}$/iu', - 33 => '/^[\x{002d}0-9א-ת]{1,63}$/iu', - ], - 'PR' => [1 => '/^[\x{002d}0-9a-záéíóúñäëïüöâêîôûàèùæçœãõ]{1,63}$/iu'], - 'PT' => [1 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu'], - 'RS' => [1 => '/^[\x{002d}0-9a-zßáâäçéëíîóôöúüýăąćčďđęěĺľłńňőŕřśşšţťůűźżž]{1,63}$/iu'], - 'RU' => [1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'], - 'SA' => [1 => '/^[\x{002d}.0-9\x{0621}-\x{063A}\x{0641}-\x{064A}\x{0660}-\x{0669}]{1,63}$/iu'], - 'SE' => [1 => '/^[\x{002d}0-9a-zäåéöü]{1,63}$/iu'], - 'SH' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿăąāćĉčċďđĕěėęēğĝġģĥħĭĩįīıĵķĺľļłńňņŋŏőōœĸŕřŗśŝšşťţŧŭůűũųūŵŷźžż]{1,63}$/iu'], - 'SI' => [ - 1 => '/^[\x{002d}0-9a-zà-öø-ÿ]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-zāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĺļľŀłńņňʼnŋōŏőœŕŗřśŝšťŧũūŭůűųŵŷźżž]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-zșț]{1,63}$/iu', - ], - 'SJ' => [1 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu'], - 'TH' => [1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'], - 'TM' => [1 => '/^[\x{002d}0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$/iu'], - 'TW' => 'Hostname/Cn.php', - 'TR' => [1 => '/^[\x{002d}0-9a-zğıüşöç]{1,63}$/iu'], - 'UA' => [1 => '/^[\x{002d}0-9a-zабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџґӂʼ]{1,63}$/iu'], - 'VE' => [1 => '/^[\x{002d}0-9a-záéíóúüñ]{1,63}$/iu'], - 'VN' => [1 => '/^[ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚÝàáâãèéêìíòóôõùúýĂăĐđĨĩŨũƠơƯư\x{1EA0}-\x{1EF9}]{1,63}$/iu'], - 'мон' => [1 => '/^[\x{002d}0-9\x{0430}-\x{044F}]{1,63}$/iu'], - 'срб' => [1 => '/^[\x{002d}0-9а-ик-шђјљњћџ]{1,63}$/iu'], - 'сайт' => [1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'], - 'онлайн' => [1 => '/^[\x{002d}0-9а-яёіїѝйўґг]{1,63}$/iu'], - '中国' => 'Hostname/Cn.php', - '中國' => 'Hostname/Cn.php', - 'ලංකා' => [1 => '/^[\x{0d80}-\x{0dff}]{1,63}$/iu'], - '香港' => 'Hostname/Cn.php', - '台湾' => 'Hostname/Cn.php', - '台灣' => 'Hostname/Cn.php', - 'امارات' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], - 'الاردن' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], - 'السعودية' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], - 'ไทย' => [1 => '/^[\x{002d}0-9a-z\x{0E01}-\x{0E3A}\x{0E40}-\x{0E4D}\x{0E50}-\x{0E59}]{1,63}$/iu'], - 'рф' => [1 => '/^[\x{002d}0-9а-яё]{1,63}$/iu'], - 'تونس' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], - 'مصر' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], - 'இலங்கை' => [1 => '/^[\x{0b80}-\x{0bff}]{1,63}$/iu'], - 'فلسطين' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], - 'شبكة' => [1 => '/^[\x{0621}-\x{0624}\x{0626}-\x{063A}\x{0641}\x{0642}\x{0644}-\x{0648}\x{067E}\x{0686}\x{0698}\x{06A9}\x{06AF}\x{06CC}\x{06F0}-\x{06F9}]{1,30}$/iu'], - ]; - - /** @var array> */ - protected $idnLength = [ - 'BIZ' => [5 => 17, 11 => 15, 12 => 20], - 'CN' => [1 => 20], - 'COM' => [3 => 17, 5 => 20], - 'HK' => [1 => 15], - 'INFO' => [4 => 17], - 'KR' => [1 => 17], - 'NET' => [3 => 17, 5 => 20], - 'ORG' => [6 => 17], - 'TW' => [1 => 20], - 'امارات' => [1 => 30], - 'الاردن' => [1 => 30], - 'السعودية' => [1 => 30], - 'تونس' => [1 => 30], - 'مصر' => [1 => 30], - 'فلسطين' => [1 => 30], - 'شبكة' => [1 => 30], - '中国' => [1 => 20], - '中國' => [1 => 20], - '香港' => [1 => 20], - '台湾' => [1 => 20], - '台灣' => [1 => 20], - ]; - - /** @var null|false|string */ - protected $tld; - - /** - * Options for the hostname validator - * - * @var array - */ - protected $options = [ - 'allow' => self::ALLOW_DNS, // Allow these hostnames - 'useIdnCheck' => true, // Check IDN domains - 'useTldCheck' => true, // Check TLD elements - 'ipValidator' => null, // IP validator to use - ]; - - // phpcs:disable Squiz.Commenting.FunctionComment.ExtraParamComment - - /** - * Sets validator options. - * - * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs - * - * @param array $options OPTIONAL Array of validator options; see Hostname::$options - * @param int $allow OPTIONAL Set what types of hostname to allow (default ALLOW_DNS) - * @param bool $useIdnCheck OPTIONAL Set whether IDN domains are validated (default true) - * @param bool $useTldCheck Set whether the TLD element of a hostname is validated (default true) - * @param Ip $ipValidator OPTIONAL - */ - public function __construct($options = []) - { - // phpcs:enable - if (! is_array($options)) { - $options = func_get_args(); - $temp['allow'] = array_shift($options); - if (! empty($options)) { - $temp['useIdnCheck'] = array_shift($options); - } - - if (! empty($options)) { - $temp['useTldCheck'] = array_shift($options); - } - - if (! empty($options)) { - $temp['ipValidator'] = array_shift($options); - } - - $options = $temp; - } - - if (! array_key_exists('ipValidator', $options)) { - $options['ipValidator'] = null; - } - - parent::__construct($options); - } - - /** - * Returns the set ip validator - * - * @return Ip - */ - public function getIpValidator() - { - return $this->options['ipValidator']; - } - - /** - * @param Ip $ipValidator OPTIONAL - * @return self - */ - public function setIpValidator(?Ip $ipValidator = null) - { - if ($ipValidator === null) { - $ipValidator = new Ip(); - } - - $this->options['ipValidator'] = $ipValidator; - return $this; - } - - /** - * Returns the allow option - * - * @return int - */ - public function getAllow() - { - return $this->options['allow']; - } - - /** - * Sets the allow option - * - * @param int $allow - * @return $this Provides a fluent interface - */ - public function setAllow($allow) - { - $this->options['allow'] = $allow; - return $this; - } - - /** - * Returns the set idn option - * - * @return bool - */ - public function getIdnCheck() - { - return $this->options['useIdnCheck']; - } - - /** - * Set whether IDN domains are validated - * - * This only applies when DNS hostnames are validated - * - * @param bool $useIdnCheck Set to true to validate IDN domains - * @return $this - */ - public function useIdnCheck($useIdnCheck) - { - $this->options['useIdnCheck'] = (bool) $useIdnCheck; - return $this; - } - - /** - * Returns the set tld option - * - * @return bool - */ - public function getTldCheck() - { - return $this->options['useTldCheck']; - } - - /** - * Set whether the TLD element of a hostname is validated - * - * This only applies when DNS hostnames are validated - * - * @param bool $useTldCheck Set to true to validate TLD elements - * @return $this - */ - public function useTldCheck($useTldCheck) - { - $this->options['useTldCheck'] = (bool) $useTldCheck; - return $this; - } - - /** - * Defined by Interface - * - * Returns true if and only if the $value is a valid hostname with respect to the current allow option - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - // Check input against IP address schema - if ( - ((preg_match('/^[0-9.]*$/', $value) && str_contains($value, '.')) - || (preg_match('/^[0-9a-f:.]*$/i', $value) && str_contains($value, ':'))) - && $this->getIpValidator()->setTranslator($this->getTranslator())->isValid($value) - ) { - if (! ($this->getAllow() & self::ALLOW_IP)) { - $this->error(self::IP_ADDRESS_NOT_ALLOWED); - return false; - } - - return true; - } - - // Handle Regex compilation failure that may happen on .biz domain with has @ character, eg: tapi4457@hsoqvf.biz - // Technically, hostname with '@' character is invalid, so mark as invalid immediately - // @see https://github.com/laminas/laminas-validator/issues/8 - if (str_contains($value, '@')) { - $this->error(self::INVALID_HOSTNAME); - return false; - } - - // Local hostnames are allowed to be partial (ending '.') - if ($this->getAllow() & self::ALLOW_LOCAL) { - if (str_ends_with($value, '.')) { - $value = substr($value, 0, -1); - if (str_ends_with($value, '.')) { - // Empty hostnames (ending '..') are not allowed - $this->error(self::INVALID_LOCAL_NAME); - return false; - } - } - } - - $domainParts = explode('.', $value); - - // Prevent partial IP V4 addresses (ending '.') - if ( - count($domainParts) === 4 && preg_match('/^[0-9.a-e:.]*$/i', $value) - && $this->getIpValidator()->setTranslator($this->getTranslator())->isValid($value) - ) { - $this->error(self::INVALID_LOCAL_NAME); - } - - $utf8StrWrapper = StringUtils::getWrapper('UTF-8'); - - // Check input against DNS hostname schema - if ( - count($domainParts) > 1 - && $utf8StrWrapper->strlen($value) >= 4 - && $utf8StrWrapper->strlen($value) <= 254 - ) { - $status = false; - - do { - // First check TLD - $matches = []; - if ( - preg_match('/([^.]{2,63})$/u', end($domainParts), $matches) - || (array_key_exists(end($domainParts), $this->validIdns)) - ) { - reset($domainParts); - - // Hostname characters are: *(label dot)(label dot label); max 254 chars - // label: id-prefix [*ldh{61} id-prefix]; max 63 chars - // id-prefix: alpha / digit - // ldh: alpha / digit / dash - - $this->tld = $matches[1]; - // Decode Punycode TLD to IDN - if (str_starts_with($this->tld, 'xn--')) { - $this->tld = $this->decodePunycode(substr($this->tld, 4)); - if ($this->tld === false) { - return false; - } - } else { - $this->tld = strtoupper($this->tld); - } - - // Match TLD against known list - $removedTld = false; - if ($this->getTldCheck()) { - if ( - ! in_array(strtolower($this->tld), $this->validTlds) - && ! in_array($this->tld, $this->validTlds) - ) { - $this->error(self::UNKNOWN_TLD); - $status = false; - break; - } - // We have already validated that the TLD is fine. We don't want it to go through the below - // checks as new UTF-8 TLDs will incorrectly fail if there is no IDN regex for it. - array_pop($domainParts); - $removedTld = true; - } - - /** - * Match against IDN hostnames - * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames - * - * @see Hostname\Interface - */ - $regexChars = [0 => '/^[a-z0-9\x2d]{1,63}$/i']; - if ($this->getIdnCheck() && isset($this->validIdns[$this->tld])) { - if (is_string($this->validIdns[$this->tld])) { - $regexChars += include __DIR__ . '/' . $this->validIdns[$this->tld]; - } else { - $regexChars += $this->validIdns[$this->tld]; - } - } - - // Check each hostname part - $check = 0; - $lastDomainPart = end($domainParts); - if (! $removedTld) { - $lastDomainPart = prev($domainParts); - } - foreach ($domainParts as $domainPart) { - // Decode Punycode domain names to IDN - if (str_starts_with($domainPart, 'xn--')) { - $domainPart = $this->decodePunycode(substr($domainPart, 4)); - if ($domainPart === false) { - return false; - } - } - - // Skip following checks if domain part is empty, as it definitely is not a valid hostname then - if ($domainPart === '') { - $this->error(self::INVALID_HOSTNAME); - $status = false; - break 2; - } - - // Check dash (-) does not start, end or appear in 3rd and 4th positions - if ( - $utf8StrWrapper->strpos($domainPart, '-') === 0 - || ($utf8StrWrapper->strlen($domainPart) > 2 - && $utf8StrWrapper->strpos($domainPart, '-', 2) === 2 - && $utf8StrWrapper->strpos($domainPart, '-', 3) === 3 - ) - || $utf8StrWrapper->substr($domainPart, -1) === '-' - ) { - $this->error(self::INVALID_DASH); - $status = false; - break 2; - } - - // Check each domain part - $checked = false; - $isSubDomain = $domainPart !== $lastDomainPart; - $partRegexChars = $isSubDomain ? ['/^[a-z0-9_\x2d]{1,63}$/i'] + $regexChars : $regexChars; - foreach ($partRegexChars as $regexKey => $regexChar) { - $status = preg_match($regexChar, $domainPart); - if ($status > 0) { - $length = 63; - if ( - array_key_exists($this->tld, $this->idnLength) - && array_key_exists($regexKey, $this->idnLength[$this->tld]) - ) { - $length = $this->idnLength[$this->tld]; - } - - if ($utf8StrWrapper->strlen($domainPart) > $length) { - $this->error(self::INVALID_HOSTNAME); - $status = false; - } else { - $checked = true; - break; - } - } - } - - if ($checked) { - ++$check; - } - } - - // If one of the labels doesn't match, the hostname is invalid - if ($check !== count($domainParts)) { - $this->error(self::INVALID_HOSTNAME_SCHEMA); - $status = false; - } - } else { - // Hostname not long enough - $this->error(self::UNDECIPHERABLE_TLD); - $status = false; - } - } while (false); - - // If the input passes as an Internet domain name, and domain names are allowed, then the hostname - // passes validation - if ($status && ($this->getAllow() & self::ALLOW_DNS)) { - return true; - } - } elseif ($this->getAllow() & self::ALLOW_DNS) { - $this->error(self::INVALID_HOSTNAME); - } - - // Check for URI Syntax (RFC3986) - if ($this->getAllow() & self::ALLOW_URI) { - if (preg_match("/^([a-zA-Z0-9-._~!$&\'()*+,;=]|%[[:xdigit:]]{2}){1,254}$/i", $value)) { - return true; - } - - $this->error(self::INVALID_URI); - } - - // Check input against local network name schema; last chance to pass validation - $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}[\x2e]{0,1}){1,254}$/'; - $status = preg_match($regexLocal, $value); - - // If the input passes as a local network name, and local network names are allowed, then the - // hostname passes validation - $allowLocal = $this->getAllow() & self::ALLOW_LOCAL; - if ($status && $allowLocal) { - return true; - } - - // If the input does not pass as a local network name, add a message - if (! $status) { - $this->error(self::INVALID_LOCAL_NAME); - } - - // If local network names are not allowed, add a message - if ($status && ! $allowLocal) { - $this->error(self::LOCAL_NAME_NOT_ALLOWED); - } - - return false; - } - - /** - * Decodes a punycode encoded string to it's original utf8 string - * Returns false in case of a decoding failure. - * - * @param string $encoded Punycode encoded string to decode - * @return string|false - */ - protected function decodePunycode($encoded) - { - if (! preg_match('/^[a-z0-9-]+$/i', $encoded)) { - // no punycode encoded string - $this->error(self::CANNOT_DECODE_PUNYCODE); - return false; - } - - $decoded = []; - $separator = strrpos($encoded, '-'); - if ($separator > 0) { - for ($x = 0; $x < $separator; ++$x) { - // prepare decoding matrix - $decoded[] = ord($encoded[$x]); - } - } - - $lengthd = count($decoded); - $lengthe = strlen($encoded); - - // decoding - $init = true; - $base = 72; - $index = 0; - $char = 0x80; - - for ($indexe = $separator ? $separator + 1 : 0; $indexe < $lengthe; ++$lengthd) { - for ($oldIndex = $index, $pos = 1, $key = 36; 1; $key += 36) { - $hex = ord($encoded[$indexe++]); - $digit = $hex - 48 < 10 ? $hex - 22 - : ($hex - 65 < 26 ? $hex - 65 - : ($hex - 97 < 26 ? $hex - 97 - : 36)); - - $index += $digit * $pos; - $tag = $key <= $base ? 1 : ($key >= $base + 26 ? 26 : $key - $base); - if ($digit < $tag) { - break; - } - - $pos = (int) ($pos * (36 - $tag)); - } - - $delta = intval($init ? ($index - $oldIndex) / 700 : ($index - $oldIndex) / 2); - $delta += intval($delta / ($lengthd + 1)); - for ($key = 0; $delta > 910 / 2; $key += 36) { - $delta = intval($delta / 35); - } - - $base = intval($key + 36 * $delta / ($delta + 38)); - $init = false; - $char += (int) ($index / ($lengthd + 1)); - $index %= $lengthd + 1; - if ($lengthd > 0) { - for ($i = $lengthd; $i > $index; $i--) { - $decoded[$i] = $decoded[$i - 1]; - } - } - - $decoded[$index++] = $char; - } - - // convert decoded ucs4 to utf8 string - foreach ($decoded as $key => $value) { - if ($value < 128) { - $decoded[$key] = chr($value); - } elseif ($value < 1 << 11) { - $decoded[$key] = chr(192 + ($value >> 6)); - $decoded[$key] .= chr(128 + ($value & 63)); - } elseif ($value < 1 << 16) { - $decoded[$key] = chr(224 + ($value >> 12)); - $decoded[$key] .= chr(128 + (($value >> 6) & 63)); - $decoded[$key] .= chr(128 + ($value & 63)); - } elseif ($value < 1 << 21) { - $decoded[$key] = chr(240 + ($value >> 18)); - $decoded[$key] .= chr(128 + (($value >> 12) & 63)); - $decoded[$key] .= chr(128 + (($value >> 6) & 63)); - $decoded[$key] .= chr(128 + ($value & 63)); - } else { - $this->error(self::CANNOT_DECODE_PUNYCODE); - return false; - } - } - - return implode($decoded); - } -} diff --git a/lib/laminas/laminas-validator/src/Hostname/Biz.php b/lib/laminas/laminas-validator/src/Hostname/Biz.php deleted file mode 100644 index f852cf1c2..000000000 --- a/lib/laminas/laminas-validator/src/Hostname/Biz.php +++ /dev/null @@ -1,2897 +0,0 @@ - '/^[\x{002d}0-9a-zäåæéöøü]{1,63}$/iu', - 2 => '/^[\x{002d}0-9a-záéíñóúü]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-záéíóöúüőű]{1,63}$/iu', - 4 => '/^[\x{002d}0-9a-záæéíðóöúýþ]{1,63}$/iu', - 5 => '/^[\x{AC00}-\x{D7A3}]{1,17}$/iu', - 6 => '/^[\x{002d}0-9a-ząčėęįšūųž]{1,63}$/iu', - 7 => '/^[\x{002d}0-9a-zāčēģīķļņōŗšūž]{1,63}$/iu', - 8 => '/^[\x{002d}0-9a-zàáä-éêñ-ôöøüčđńŋšŧž]{1,63}$/iu', - 9 => '/^[\x{002d}0-9a-zóąćęłńśźż]{1,63}$/iu', - 10 => '/^[\x{002d}0-9a-záàâãçéêíóôõú]{1,63}$/iu', - 11 => '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}\x{30A1}-\x{30F6}\x{30FC}' - . '\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' - . '\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' - . '\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' - . '\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' - . '\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' - . '\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' - . '\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' - . '\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' - . '\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' - . '\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' - . '\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' - . '\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' - . '\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' - . '\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' - . '\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' - . '\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' - . '\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' - . '\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' - . '\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' - . '\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' - . '\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' - . '\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' - . '\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' - . '\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' - . '\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' - . '\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' - . '\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' - . '\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' - . '\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' - . '\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' - . '\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' - . '\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' - . '\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' - . '\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' - . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' - . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' - . '\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' - . '\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' - . '\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' - . '\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' - . '\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' - . '\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' - . '\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' - . '\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' - . '\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' - . '\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' - . '\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' - . '\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' - . '\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' - . '\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' - . '\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' - . '\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' - . '\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' - . '\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' - . '\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' - . '\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' - . '\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' - . '\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' - . '\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' - . '\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' - . '\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' - . '\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' - . '\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' - . '\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' - . '\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' - . '\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' - . '\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' - . '\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' - . '\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' - . '\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' - . '\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' - . '\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' - . '\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' - . '\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' - . '\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' - . '\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' - . '\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' - . '\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' - . '\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' - . '\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' - . '\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' - . '\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' - . '\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' - . '\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' - . '\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' - . '\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' - . '\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' - . '\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' - . '\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' - . '\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' - . '\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' - . '\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' - . '\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' - . '\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' - . '\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' - . '\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' - . '\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' - . '\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' - . '\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' - . '\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' - . '\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' - . '\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' - . '\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' - . '\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' - . '\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' - . '\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' - . '\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' - . '\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' - . '\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' - . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' - . '\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' - . '\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' - . '\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' - . '\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' - . '\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' - . '\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' - . '\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' - . '\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' - . '\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' - . '\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' - . '\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' - . '\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' - . '\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' - . '\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' - . '\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' - . '\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' - . '\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' - . '\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' - . '\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' - . '\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' - . '\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' - . '\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' - . '\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' - . '\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' - . '\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' - . '\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' - . '\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' - . '\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' - . '\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' - . '\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' - . '\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' - . '\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' - . '\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' - . '\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' - . '\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' - . '\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' - . '\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' - . '\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' - . '\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' - . '\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' - . '\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' - . '\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' - . '\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' - . '\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' - . '\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' - . '\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' - . '\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' - . '\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' - . '\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' - . '\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' - . '\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' - . '\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' - . '\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' - . '\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' - . '\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' - . '\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' - . '\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' - . '\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' - . '\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' - . '\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' - . '\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' - . '\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' - . '\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' - . '\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' - . '\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' - . '\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' - . '\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' - . '\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' - . '\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' - . '\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' - . '\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' - . '\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' - . '\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' - . '\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' - . '\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' - . '\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' - . '\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' - . '\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' - . '\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' - . '\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' - . '\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' - . '\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' - . '\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' - . '\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' - . '\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' - . '\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' - . '\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' - . '\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' - . '\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' - . '\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' - . '\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' - . '\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' - . '\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' - . '\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' - . '\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' - . '\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' - . '\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' - . '\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' - . '\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' - . '\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' - . '\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' - . '\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' - . '\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' - . '\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' - . '\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' - . '\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' - . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' - . '\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' - . '\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' - . '\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' - . '\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' - . '\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' - . '\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' - . '\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' - . '\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' - . '\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' - . '\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' - . '\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' - . '\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' - . '\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' - . '\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' - . '\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' - . '\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' - . '\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' - . '\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' - . '\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' - . '\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' - . '\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' - . '\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' - . '\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' - . '\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' - . '\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' - . '\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' - . '\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' - . '\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' - . '\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' - . '\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' - . '\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' - . '\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' - . '\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' - . '\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' - . '\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' - . '\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' - . '\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' - . '\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' - . '\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' - . '\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' - . '\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' - . '\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' - . '\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' - . '\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' - . '\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' - . '\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' - . '\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' - . '\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' - . '\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' - . '\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' - . '\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' - . '\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' - . '\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' - . '\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' - . '\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' - . '\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' - . '\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' - . '\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' - . '\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' - . '\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' - . '\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' - . '\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' - . '\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' - . '\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' - . '\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' - . '\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' - . '\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' - . '\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' - . '\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' - . '\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' - . '\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' - . '\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' - . '\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' - . '\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' - . '\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' - . '\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' - . '\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' - . '\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' - . '\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' - . '\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' - . '\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' - . '\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' - . '\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' - . '\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' - . '\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' - . '\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' - . '\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' - . '\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' - . '\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' - . '\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' - . '\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' - . '\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' - . '\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' - . '\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' - . '\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' - . '\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' - . '\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' - . '\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' - . '\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' - . '\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' - . '\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' - . '\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' - . '\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' - . '\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' - . '\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' - . '\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' - . '\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' - . '\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' - . '\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' - . '\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' - . '\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' - . '\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' - . '\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' - . '\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' - . '\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' - . '\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' - . '\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' - . '\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' - . '\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' - . '\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' - . '\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' - . '\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' - . '\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' - . '\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' - . '\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' - . '\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' - . '\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' - . '\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' - . '\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' - . '\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' - . '\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' - . '\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' - . '\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' - . '\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' - . '\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' - . '\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' - . '\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' - . '\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' - . '\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' - . '\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' - . '\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' - . '\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' - . '\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' - . '\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' - . '\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' - . '\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' - . '\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' - . '\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' - . '\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' - . '\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' - . '\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' - . '\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' - . '\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' - . '\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' - . '\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' - . '\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' - . '\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' - . '\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' - . '\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' - . '\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' - . '\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' - . '\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' - . '\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' - . '\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' - . '\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' - . '\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' - . '\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' - . '\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' - . '\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' - . '\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' - . '\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' - . '\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' - . '\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' - . '\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' - . '\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' - . '\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' - . '\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' - . '\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' - . '\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' - . '\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' - . '\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' - . '\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' - . '\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' - . '\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' - . '\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' - . '\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' - . '\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' - . '\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' - . '\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' - . '\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' - . '\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' - . '\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' - . '\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' - . '\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' - . '\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' - . '\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' - . '\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' - . '\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' - . '\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' - . '\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' - . '\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' - . '\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' - . '\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' - . '\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' - . '\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' - . '\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' - . '\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' - . '\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' - . '\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' - . '\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' - . '\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' - . '\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' - . '\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' - . '\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' - . '\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' - . '\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' - . '\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' - . '\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' - . '\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' - . '\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' - . '\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' - . '\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' - . '\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' - . '\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' - . '\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' - . '\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' - . '\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' - . '\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' - . '\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' - . '\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' - . '\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' - . '\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' - . '\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' - . '\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' - . '\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' - . '\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' - . '\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' - . '\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' - . '\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' - . '\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' - . '\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' - . '\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' - . '\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' - . '\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' - . '\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' - . '\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' - . '\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' - . '\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' - . '\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' - . '\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' - . '\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' - . '\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' - . '\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' - . '\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' - . '\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' - . '\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' - . '\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' - . '\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' - . '\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' - . '\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' - . '\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' - . '\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' - . '\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' - . '\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' - . '\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' - . '\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' - . '\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' - . '\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' - . '\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' - . '\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' - . '\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' - . '\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' - . '\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' - . '\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' - . '\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' - . '\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' - . '\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' - . '\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' - . '\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' - . '\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' - . '\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' - . '\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' - . '\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' - . '\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' - . '\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' - . '\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' - . '\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' - . '\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' - . '\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' - . '\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' - . '\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' - . '\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' - . '\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' - . '\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' - . '\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' - . '\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' - . '\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' - . '\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' - . '\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' - . '\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' - . '\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' - . '\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' - . '\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' - . '\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' - . '\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' - . '\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' - . '\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' - . '\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' - . '\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' - . '\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' - . '\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' - . '\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' - . '\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' - . '\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' - . '\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' - . '\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' - . '\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' - . '\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' - . '\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' - . '\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' - . '\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' - . '\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' - . '\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' - . '\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' - . '\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' - . '\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' - . '\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' - . '\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' - . '\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' - . '\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' - . '\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' - . '\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' - . '\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' - . '\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' - . '\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' - . '\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' - . '\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' - . '\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' - . '\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' - . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' - . '\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' - . '\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' - . '\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' - . '\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' - . '\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' - . '\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' - . '\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' - . '\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' - . '\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' - . '\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' - . '\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' - . '\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' - . '\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' - . '\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' - . '\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' - . '\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' - . '\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' - . '\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' - . '\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' - . '\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' - . '\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' - . '\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' - . '\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' - . '\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' - . '\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' - . '\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' - . '\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' - . '\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' - . '\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' - . '\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' - . '\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' - . '\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' - . '\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' - . '\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' - . '\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' - . '\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' - . '\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' - . '\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' - . '\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' - . '\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' - . '\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' - . '\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' - . '\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' - . '\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' - . '\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' - . '\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' - . '\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' - . '\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' - . '\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' - . '\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' - . '\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' - . '\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' - . '\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' - . '\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' - . '\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' - . '\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' - . '\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' - . '\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' - . '\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' - . '\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' - . '\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' - . '\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' - . '\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' - . '\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' - . '\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' - . '\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' - . '\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' - . '\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' - . '\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' - . '\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' - . '\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' - . '\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' - . '\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' - . '\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' - . '\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' - . '\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' - . '\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' - . '\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' - . '\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' - . '\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' - . '\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' - . '\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' - . '\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' - . '\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' - . '\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' - . '\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' - . '\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' - . '\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' - . '\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' - . '\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' - . '\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' - . '\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' - . '\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' - . '\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' - . '\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' - . '\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' - . '\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' - . '\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' - . '\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' - . '\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' - . '\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' - . '\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' - . '\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' - . '\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' - . '\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' - . '\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' - . '\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' - . '\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' - . '\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' - . '\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' - . '\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' - . '\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' - . '\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' - . '\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' - . '\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' - . '\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' - . '\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' - . '\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' - . '\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' - . '\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' - . '\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' - . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' - . '\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' - . '\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' - . '\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' - . '\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' - . '\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' - . '\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' - . '\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' - . '\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' - . '\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' - . '\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' - . '\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' - . '\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' - . '\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' - . '\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' - . '\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' - . '\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' - . '\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' - . '\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' - . '\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' - . '\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' - . '\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' - . '\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' - . '\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' - . '\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' - . '\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' - . '\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' - . '\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' - . '\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu', - 12 => '/^[\x{002d}0-9a-z\x{3447}\x{3473}\x{359E}\x{360E}\x{361A}\x{3918}\x{396E}\x{39CF}\x{39D0}' - . '\x{39DF}\x{3A73}\x{3B4E}\x{3C6E}\x{3CE0}\x{4056}\x{415F}\x{4337}\x{43AC}' - . '\x{43B1}\x{43DD}\x{44D6}\x{464C}\x{4661}\x{4723}\x{4729}\x{477C}\x{478D}' - . '\x{4947}\x{497A}\x{497D}\x{4982}\x{4983}\x{4985}\x{4986}\x{499B}\x{499F}' - . '\x{49B6}\x{49B7}\x{4C77}\x{4C9F}\x{4CA0}\x{4CA1}\x{4CA2}\x{4CA3}\x{4D13}' - . '\x{4D14}\x{4D15}\x{4D16}\x{4D17}\x{4D18}\x{4D19}\x{4DAE}\x{4E00}\x{4E01}' - . '\x{4E02}\x{4E03}\x{4E04}\x{4E05}\x{4E06}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' - . '\x{4E0B}\x{4E0C}\x{4E0D}\x{4E0E}\x{4E0F}\x{4E10}\x{4E11}\x{4E13}\x{4E14}' - . '\x{4E15}\x{4E16}\x{4E17}\x{4E18}\x{4E19}\x{4E1A}\x{4E1B}\x{4E1C}\x{4E1D}' - . '\x{4E1E}\x{4E1F}\x{4E20}\x{4E21}\x{4E22}\x{4E23}\x{4E24}\x{4E25}\x{4E26}' - . '\x{4E27}\x{4E28}\x{4E2A}\x{4E2B}\x{4E2C}\x{4E2D}\x{4E2E}\x{4E2F}\x{4E30}' - . '\x{4E31}\x{4E32}\x{4E33}\x{4E34}\x{4E35}\x{4E36}\x{4E37}\x{4E38}\x{4E39}' - . '\x{4E3A}\x{4E3B}\x{4E3C}\x{4E3D}\x{4E3E}\x{4E3F}\x{4E40}\x{4E41}\x{4E42}' - . '\x{4E43}\x{4E44}\x{4E45}\x{4E46}\x{4E47}\x{4E48}\x{4E49}\x{4E4A}\x{4E4B}' - . '\x{4E4C}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E50}\x{4E51}\x{4E52}\x{4E53}\x{4E54}' - . '\x{4E56}\x{4E57}\x{4E58}\x{4E59}\x{4E5A}\x{4E5B}\x{4E5C}\x{4E5D}\x{4E5E}' - . '\x{4E5F}\x{4E60}\x{4E61}\x{4E62}\x{4E63}\x{4E64}\x{4E65}\x{4E66}\x{4E67}' - . '\x{4E69}\x{4E6A}\x{4E6B}\x{4E6C}\x{4E6D}\x{4E6E}\x{4E6F}\x{4E70}\x{4E71}' - . '\x{4E72}\x{4E73}\x{4E74}\x{4E75}\x{4E76}\x{4E77}\x{4E78}\x{4E7A}\x{4E7B}' - . '\x{4E7C}\x{4E7D}\x{4E7E}\x{4E7F}\x{4E80}\x{4E81}\x{4E82}\x{4E83}\x{4E84}' - . '\x{4E85}\x{4E86}\x{4E87}\x{4E88}\x{4E89}\x{4E8B}\x{4E8C}\x{4E8D}\x{4E8E}' - . '\x{4E8F}\x{4E90}\x{4E91}\x{4E92}\x{4E93}\x{4E94}\x{4E95}\x{4E97}\x{4E98}' - . '\x{4E99}\x{4E9A}\x{4E9B}\x{4E9C}\x{4E9D}\x{4E9E}\x{4E9F}\x{4EA0}\x{4EA1}' - . '\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA7}\x{4EA8}\x{4EA9}\x{4EAA}\x{4EAB}' - . '\x{4EAC}\x{4EAD}\x{4EAE}\x{4EAF}\x{4EB0}\x{4EB1}\x{4EB2}\x{4EB3}\x{4EB4}' - . '\x{4EB5}\x{4EB6}\x{4EB7}\x{4EB8}\x{4EB9}\x{4EBA}\x{4EBB}\x{4EBD}\x{4EBE}' - . '\x{4EBF}\x{4EC0}\x{4EC1}\x{4EC2}\x{4EC3}\x{4EC4}\x{4EC5}\x{4EC6}\x{4EC7}' - . '\x{4EC8}\x{4EC9}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED0}\x{4ED1}' - . '\x{4ED2}\x{4ED3}\x{4ED4}\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDA}' - . '\x{4EDB}\x{4EDC}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE0}\x{4EE1}\x{4EE2}\x{4EE3}' - . '\x{4EE4}\x{4EE5}\x{4EE6}\x{4EE8}\x{4EE9}\x{4EEA}\x{4EEB}\x{4EEC}\x{4EEF}' - . '\x{4EF0}\x{4EF1}\x{4EF2}\x{4EF3}\x{4EF4}\x{4EF5}\x{4EF6}\x{4EF7}\x{4EFB}' - . '\x{4EFD}\x{4EFF}\x{4F00}\x{4F01}\x{4F02}\x{4F03}\x{4F04}\x{4F05}\x{4F06}' - . '\x{4F08}\x{4F09}\x{4F0A}\x{4F0B}\x{4F0C}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}' - . '\x{4F11}\x{4F12}\x{4F13}\x{4F14}\x{4F15}\x{4F17}\x{4F18}\x{4F19}\x{4F1A}' - . '\x{4F1B}\x{4F1C}\x{4F1D}\x{4F1E}\x{4F1F}\x{4F20}\x{4F21}\x{4F22}\x{4F23}' - . '\x{4F24}\x{4F25}\x{4F26}\x{4F27}\x{4F29}\x{4F2A}\x{4F2B}\x{4F2C}\x{4F2D}' - . '\x{4F2E}\x{4F2F}\x{4F30}\x{4F32}\x{4F33}\x{4F34}\x{4F36}\x{4F38}\x{4F39}' - . '\x{4F3A}\x{4F3B}\x{4F3C}\x{4F3D}\x{4F3E}\x{4F3F}\x{4F41}\x{4F42}\x{4F43}' - . '\x{4F45}\x{4F46}\x{4F47}\x{4F48}\x{4F49}\x{4F4A}\x{4F4B}\x{4F4C}\x{4F4D}' - . '\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}\x{4F52}\x{4F53}\x{4F54}\x{4F55}\x{4F56}' - . '\x{4F57}\x{4F58}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}\x{4F5F}' - . '\x{4F60}\x{4F61}\x{4F62}\x{4F63}\x{4F64}\x{4F65}\x{4F66}\x{4F67}\x{4F68}' - . '\x{4F69}\x{4F6A}\x{4F6B}\x{4F6C}\x{4F6D}\x{4F6E}\x{4F6F}\x{4F70}\x{4F72}' - . '\x{4F73}\x{4F74}\x{4F75}\x{4F76}\x{4F77}\x{4F78}\x{4F79}\x{4F7A}\x{4F7B}' - . '\x{4F7C}\x{4F7D}\x{4F7E}\x{4F7F}\x{4F80}\x{4F81}\x{4F82}\x{4F83}\x{4F84}' - . '\x{4F85}\x{4F86}\x{4F87}\x{4F88}\x{4F89}\x{4F8A}\x{4F8B}\x{4F8D}\x{4F8F}' - . '\x{4F90}\x{4F91}\x{4F92}\x{4F93}\x{4F94}\x{4F95}\x{4F96}\x{4F97}\x{4F98}' - . '\x{4F99}\x{4F9A}\x{4F9B}\x{4F9C}\x{4F9D}\x{4F9E}\x{4F9F}\x{4FA0}\x{4FA1}' - . '\x{4FA3}\x{4FA4}\x{4FA5}\x{4FA6}\x{4FA7}\x{4FA8}\x{4FA9}\x{4FAA}\x{4FAB}' - . '\x{4FAC}\x{4FAE}\x{4FAF}\x{4FB0}\x{4FB1}\x{4FB2}\x{4FB3}\x{4FB4}\x{4FB5}' - . '\x{4FB6}\x{4FB7}\x{4FB8}\x{4FB9}\x{4FBA}\x{4FBB}\x{4FBC}\x{4FBE}\x{4FBF}' - . '\x{4FC0}\x{4FC1}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FC5}\x{4FC7}\x{4FC9}\x{4FCA}' - . '\x{4FCB}\x{4FCD}\x{4FCE}\x{4FCF}\x{4FD0}\x{4FD1}\x{4FD2}\x{4FD3}\x{4FD4}' - . '\x{4FD5}\x{4FD6}\x{4FD7}\x{4FD8}\x{4FD9}\x{4FDA}\x{4FDB}\x{4FDC}\x{4FDD}' - . '\x{4FDE}\x{4FDF}\x{4FE0}\x{4FE1}\x{4FE3}\x{4FE4}\x{4FE5}\x{4FE6}\x{4FE7}' - . '\x{4FE8}\x{4FE9}\x{4FEA}\x{4FEB}\x{4FEC}\x{4FED}\x{4FEE}\x{4FEF}\x{4FF0}' - . '\x{4FF1}\x{4FF2}\x{4FF3}\x{4FF4}\x{4FF5}\x{4FF6}\x{4FF7}\x{4FF8}\x{4FF9}' - . '\x{4FFA}\x{4FFB}\x{4FFE}\x{4FFF}\x{5000}\x{5001}\x{5002}\x{5003}\x{5004}' - . '\x{5005}\x{5006}\x{5007}\x{5008}\x{5009}\x{500A}\x{500B}\x{500C}\x{500D}' - . '\x{500E}\x{500F}\x{5011}\x{5012}\x{5013}\x{5014}\x{5015}\x{5016}\x{5017}' - . '\x{5018}\x{5019}\x{501A}\x{501B}\x{501C}\x{501D}\x{501E}\x{501F}\x{5020}' - . '\x{5021}\x{5022}\x{5023}\x{5024}\x{5025}\x{5026}\x{5027}\x{5028}\x{5029}' - . '\x{502A}\x{502B}\x{502C}\x{502D}\x{502E}\x{502F}\x{5030}\x{5031}\x{5032}' - . '\x{5033}\x{5035}\x{5036}\x{5037}\x{5039}\x{503A}\x{503B}\x{503C}\x{503E}' - . '\x{503F}\x{5040}\x{5041}\x{5043}\x{5044}\x{5045}\x{5046}\x{5047}\x{5048}' - . '\x{5049}\x{504A}\x{504B}\x{504C}\x{504D}\x{504E}\x{504F}\x{5051}\x{5053}' - . '\x{5054}\x{5055}\x{5056}\x{5057}\x{5059}\x{505A}\x{505B}\x{505C}\x{505D}' - . '\x{505E}\x{505F}\x{5060}\x{5061}\x{5062}\x{5063}\x{5064}\x{5065}\x{5066}' - . '\x{5067}\x{5068}\x{5069}\x{506A}\x{506B}\x{506C}\x{506D}\x{506E}\x{506F}' - . '\x{5070}\x{5071}\x{5072}\x{5073}\x{5074}\x{5075}\x{5076}\x{5077}\x{5078}' - . '\x{5079}\x{507A}\x{507B}\x{507D}\x{507E}\x{507F}\x{5080}\x{5082}\x{5083}' - . '\x{5084}\x{5085}\x{5086}\x{5087}\x{5088}\x{5089}\x{508A}\x{508B}\x{508C}' - . '\x{508D}\x{508E}\x{508F}\x{5090}\x{5091}\x{5092}\x{5094}\x{5095}\x{5096}' - . '\x{5098}\x{5099}\x{509A}\x{509B}\x{509C}\x{509D}\x{509E}\x{50A2}\x{50A3}' - . '\x{50A4}\x{50A5}\x{50A6}\x{50A7}\x{50A8}\x{50A9}\x{50AA}\x{50AB}\x{50AC}' - . '\x{50AD}\x{50AE}\x{50AF}\x{50B0}\x{50B1}\x{50B2}\x{50B3}\x{50B4}\x{50B5}' - . '\x{50B6}\x{50B7}\x{50B8}\x{50BA}\x{50BB}\x{50BC}\x{50BD}\x{50BE}\x{50BF}' - . '\x{50C0}\x{50C1}\x{50C2}\x{50C4}\x{50C5}\x{50C6}\x{50C7}\x{50C8}\x{50C9}' - . '\x{50CA}\x{50CB}\x{50CC}\x{50CD}\x{50CE}\x{50CF}\x{50D0}\x{50D1}\x{50D2}' - . '\x{50D3}\x{50D4}\x{50D5}\x{50D6}\x{50D7}\x{50D9}\x{50DA}\x{50DB}\x{50DC}' - . '\x{50DD}\x{50DE}\x{50E0}\x{50E3}\x{50E4}\x{50E5}\x{50E6}\x{50E7}\x{50E8}' - . '\x{50E9}\x{50EA}\x{50EC}\x{50ED}\x{50EE}\x{50EF}\x{50F0}\x{50F1}\x{50F2}' - . '\x{50F3}\x{50F5}\x{50F6}\x{50F8}\x{50F9}\x{50FA}\x{50FB}\x{50FC}\x{50FD}' - . '\x{50FE}\x{50FF}\x{5100}\x{5101}\x{5102}\x{5103}\x{5104}\x{5105}\x{5106}' - . '\x{5107}\x{5108}\x{5109}\x{510A}\x{510B}\x{510C}\x{510D}\x{510E}\x{510F}' - . '\x{5110}\x{5111}\x{5112}\x{5113}\x{5114}\x{5115}\x{5116}\x{5117}\x{5118}' - . '\x{5119}\x{511A}\x{511C}\x{511D}\x{511E}\x{511F}\x{5120}\x{5121}\x{5122}' - . '\x{5123}\x{5124}\x{5125}\x{5126}\x{5127}\x{5129}\x{512A}\x{512C}\x{512D}' - . '\x{512E}\x{512F}\x{5130}\x{5131}\x{5132}\x{5133}\x{5134}\x{5135}\x{5136}' - . '\x{5137}\x{5138}\x{5139}\x{513A}\x{513B}\x{513C}\x{513D}\x{513E}\x{513F}' - . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' - . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5151}\x{5152}\x{5154}\x{5155}' - . '\x{5156}\x{5157}\x{5159}\x{515A}\x{515B}\x{515C}\x{515D}\x{515E}\x{515F}' - . '\x{5161}\x{5162}\x{5163}\x{5165}\x{5166}\x{5167}\x{5168}\x{5169}\x{516A}' - . '\x{516B}\x{516C}\x{516D}\x{516E}\x{516F}\x{5170}\x{5171}\x{5173}\x{5174}' - . '\x{5175}\x{5176}\x{5177}\x{5178}\x{5179}\x{517A}\x{517B}\x{517C}\x{517D}' - . '\x{517F}\x{5180}\x{5181}\x{5182}\x{5185}\x{5186}\x{5187}\x{5188}\x{5189}' - . '\x{518A}\x{518B}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}\x{5193}' - . '\x{5194}\x{5195}\x{5196}\x{5197}\x{5198}\x{5199}\x{519A}\x{519B}\x{519C}' - . '\x{519D}\x{519E}\x{519F}\x{51A0}\x{51A2}\x{51A4}\x{51A5}\x{51A6}\x{51A7}' - . '\x{51A8}\x{51AA}\x{51AB}\x{51AC}\x{51AE}\x{51AF}\x{51B0}\x{51B1}\x{51B2}' - . '\x{51B3}\x{51B5}\x{51B6}\x{51B7}\x{51B9}\x{51BB}\x{51BC}\x{51BD}\x{51BE}' - . '\x{51BF}\x{51C0}\x{51C1}\x{51C3}\x{51C4}\x{51C5}\x{51C6}\x{51C7}\x{51C8}' - . '\x{51C9}\x{51CA}\x{51CB}\x{51CC}\x{51CD}\x{51CE}\x{51CF}\x{51D0}\x{51D1}' - . '\x{51D4}\x{51D5}\x{51D6}\x{51D7}\x{51D8}\x{51D9}\x{51DA}\x{51DB}\x{51DC}' - . '\x{51DD}\x{51DE}\x{51E0}\x{51E1}\x{51E2}\x{51E3}\x{51E4}\x{51E5}\x{51E7}' - . '\x{51E8}\x{51E9}\x{51EA}\x{51EB}\x{51ED}\x{51EF}\x{51F0}\x{51F1}\x{51F3}' - . '\x{51F4}\x{51F5}\x{51F6}\x{51F7}\x{51F8}\x{51F9}\x{51FA}\x{51FB}\x{51FC}' - . '\x{51FD}\x{51FE}\x{51FF}\x{5200}\x{5201}\x{5202}\x{5203}\x{5204}\x{5205}' - . '\x{5206}\x{5207}\x{5208}\x{5209}\x{520A}\x{520B}\x{520C}\x{520D}\x{520E}' - . '\x{520F}\x{5210}\x{5211}\x{5212}\x{5213}\x{5214}\x{5215}\x{5216}\x{5217}' - . '\x{5218}\x{5219}\x{521A}\x{521B}\x{521C}\x{521D}\x{521E}\x{521F}\x{5220}' - . '\x{5221}\x{5222}\x{5223}\x{5224}\x{5225}\x{5226}\x{5228}\x{5229}\x{522A}' - . '\x{522B}\x{522C}\x{522D}\x{522E}\x{522F}\x{5230}\x{5231}\x{5232}\x{5233}' - . '\x{5234}\x{5235}\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{523C}' - . '\x{523D}\x{523E}\x{523F}\x{5240}\x{5241}\x{5242}\x{5243}\x{5244}\x{5245}' - . '\x{5246}\x{5247}\x{5248}\x{5249}\x{524A}\x{524B}\x{524C}\x{524D}\x{524E}' - . '\x{5250}\x{5251}\x{5252}\x{5254}\x{5255}\x{5256}\x{5257}\x{5258}\x{5259}' - . '\x{525A}\x{525B}\x{525C}\x{525D}\x{525E}\x{525F}\x{5260}\x{5261}\x{5262}' - . '\x{5263}\x{5264}\x{5265}\x{5267}\x{5268}\x{5269}\x{526A}\x{526B}\x{526C}' - . '\x{526D}\x{526E}\x{526F}\x{5270}\x{5272}\x{5273}\x{5274}\x{5275}\x{5276}' - . '\x{5277}\x{5278}\x{527A}\x{527B}\x{527C}\x{527D}\x{527E}\x{527F}\x{5280}' - . '\x{5281}\x{5282}\x{5283}\x{5284}\x{5286}\x{5287}\x{5288}\x{5289}\x{528A}' - . '\x{528B}\x{528C}\x{528D}\x{528F}\x{5290}\x{5291}\x{5292}\x{5293}\x{5294}' - . '\x{5295}\x{5296}\x{5297}\x{5298}\x{5299}\x{529A}\x{529B}\x{529C}\x{529D}' - . '\x{529E}\x{529F}\x{52A0}\x{52A1}\x{52A2}\x{52A3}\x{52A5}\x{52A6}\x{52A7}' - . '\x{52A8}\x{52A9}\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52AE}\x{52AF}\x{52B0}' - . '\x{52B1}\x{52B2}\x{52B3}\x{52B4}\x{52B5}\x{52B6}\x{52B7}\x{52B8}\x{52B9}' - . '\x{52BA}\x{52BB}\x{52BC}\x{52BD}\x{52BE}\x{52BF}\x{52C0}\x{52C1}\x{52C2}' - . '\x{52C3}\x{52C6}\x{52C7}\x{52C9}\x{52CA}\x{52CB}\x{52CD}\x{52CF}\x{52D0}' - . '\x{52D2}\x{52D3}\x{52D5}\x{52D6}\x{52D7}\x{52D8}\x{52D9}\x{52DA}\x{52DB}' - . '\x{52DC}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}\x{52E4}\x{52E6}' - . '\x{52E7}\x{52E8}\x{52E9}\x{52EA}\x{52EB}\x{52EC}\x{52ED}\x{52EF}\x{52F0}' - . '\x{52F1}\x{52F2}\x{52F3}\x{52F4}\x{52F5}\x{52F6}\x{52F7}\x{52F8}\x{52F9}' - . '\x{52FA}\x{52FB}\x{52FC}\x{52FD}\x{52FE}\x{52FF}\x{5300}\x{5301}\x{5302}' - . '\x{5305}\x{5306}\x{5307}\x{5308}\x{5309}\x{530A}\x{530B}\x{530C}\x{530D}' - . '\x{530E}\x{530F}\x{5310}\x{5311}\x{5312}\x{5313}\x{5314}\x{5315}\x{5316}' - . '\x{5317}\x{5319}\x{531A}\x{531C}\x{531D}\x{531F}\x{5320}\x{5321}\x{5322}' - . '\x{5323}\x{5324}\x{5325}\x{5326}\x{5328}\x{532A}\x{532B}\x{532C}\x{532D}' - . '\x{532E}\x{532F}\x{5330}\x{5331}\x{5333}\x{5334}\x{5337}\x{5339}\x{533A}' - . '\x{533B}\x{533C}\x{533D}\x{533E}\x{533F}\x{5340}\x{5341}\x{5343}\x{5344}' - . '\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}\x{534A}\x{534B}\x{534C}\x{534D}' - . '\x{534E}\x{534F}\x{5350}\x{5351}\x{5352}\x{5353}\x{5354}\x{5355}\x{5356}' - . '\x{5357}\x{5358}\x{5359}\x{535A}\x{535C}\x{535E}\x{535F}\x{5360}\x{5361}' - . '\x{5362}\x{5363}\x{5364}\x{5365}\x{5366}\x{5367}\x{5369}\x{536B}\x{536C}' - . '\x{536E}\x{536F}\x{5370}\x{5371}\x{5372}\x{5373}\x{5374}\x{5375}\x{5376}' - . '\x{5377}\x{5378}\x{5379}\x{537A}\x{537B}\x{537C}\x{537D}\x{537E}\x{537F}' - . '\x{5381}\x{5382}\x{5383}\x{5384}\x{5385}\x{5386}\x{5387}\x{5388}\x{5389}' - . '\x{538A}\x{538B}\x{538C}\x{538D}\x{538E}\x{538F}\x{5390}\x{5391}\x{5392}' - . '\x{5393}\x{5394}\x{5395}\x{5396}\x{5397}\x{5398}\x{5399}\x{539A}\x{539B}' - . '\x{539C}\x{539D}\x{539E}\x{539F}\x{53A0}\x{53A2}\x{53A3}\x{53A4}\x{53A5}' - . '\x{53A6}\x{53A7}\x{53A8}\x{53A9}\x{53AC}\x{53AD}\x{53AE}\x{53B0}\x{53B1}' - . '\x{53B2}\x{53B3}\x{53B4}\x{53B5}\x{53B6}\x{53B7}\x{53B8}\x{53B9}\x{53BB}' - . '\x{53BC}\x{53BD}\x{53BE}\x{53BF}\x{53C0}\x{53C1}\x{53C2}\x{53C3}\x{53C4}' - . '\x{53C6}\x{53C7}\x{53C8}\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}' - . '\x{53D0}\x{53D1}\x{53D2}\x{53D3}\x{53D4}\x{53D5}\x{53D6}\x{53D7}\x{53D8}' - . '\x{53D9}\x{53DB}\x{53DC}\x{53DF}\x{53E0}\x{53E1}\x{53E2}\x{53E3}\x{53E4}' - . '\x{53E5}\x{53E6}\x{53E8}\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}' - . '\x{53EF}\x{53F0}\x{53F1}\x{53F2}\x{53F3}\x{53F4}\x{53F5}\x{53F6}\x{53F7}' - . '\x{53F8}\x{53F9}\x{53FA}\x{53FB}\x{53FC}\x{53FD}\x{53FE}\x{5401}\x{5402}' - . '\x{5403}\x{5404}\x{5405}\x{5406}\x{5407}\x{5408}\x{5409}\x{540A}\x{540B}' - . '\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}\x{5411}\x{5412}\x{5413}\x{5414}' - . '\x{5415}\x{5416}\x{5417}\x{5418}\x{5419}\x{541B}\x{541C}\x{541D}\x{541E}' - . '\x{541F}\x{5420}\x{5421}\x{5423}\x{5424}\x{5425}\x{5426}\x{5427}\x{5428}' - . '\x{5429}\x{542A}\x{542B}\x{542C}\x{542D}\x{542E}\x{542F}\x{5430}\x{5431}' - . '\x{5432}\x{5433}\x{5434}\x{5435}\x{5436}\x{5437}\x{5438}\x{5439}\x{543A}' - . '\x{543B}\x{543C}\x{543D}\x{543E}\x{543F}\x{5440}\x{5441}\x{5442}\x{5443}' - . '\x{5444}\x{5445}\x{5446}\x{5447}\x{5448}\x{5449}\x{544A}\x{544B}\x{544D}' - . '\x{544E}\x{544F}\x{5450}\x{5451}\x{5452}\x{5453}\x{5454}\x{5455}\x{5456}' - . '\x{5457}\x{5458}\x{5459}\x{545A}\x{545B}\x{545C}\x{545E}\x{545F}\x{5460}' - . '\x{5461}\x{5462}\x{5463}\x{5464}\x{5465}\x{5466}\x{5467}\x{5468}\x{546A}' - . '\x{546B}\x{546C}\x{546D}\x{546E}\x{546F}\x{5470}\x{5471}\x{5472}\x{5473}' - . '\x{5474}\x{5475}\x{5476}\x{5477}\x{5478}\x{5479}\x{547A}\x{547B}\x{547C}' - . '\x{547D}\x{547E}\x{547F}\x{5480}\x{5481}\x{5482}\x{5483}\x{5484}\x{5485}' - . '\x{5486}\x{5487}\x{5488}\x{5489}\x{548B}\x{548C}\x{548D}\x{548E}\x{548F}' - . '\x{5490}\x{5491}\x{5492}\x{5493}\x{5494}\x{5495}\x{5496}\x{5497}\x{5498}' - . '\x{5499}\x{549A}\x{549B}\x{549C}\x{549D}\x{549E}\x{549F}\x{54A0}\x{54A1}' - . '\x{54A2}\x{54A3}\x{54A4}\x{54A5}\x{54A6}\x{54A7}\x{54A8}\x{54A9}\x{54AA}' - . '\x{54AB}\x{54AC}\x{54AD}\x{54AE}\x{54AF}\x{54B0}\x{54B1}\x{54B2}\x{54B3}' - . '\x{54B4}\x{54B6}\x{54B7}\x{54B8}\x{54B9}\x{54BA}\x{54BB}\x{54BC}\x{54BD}' - . '\x{54BE}\x{54BF}\x{54C0}\x{54C1}\x{54C2}\x{54C3}\x{54C4}\x{54C5}\x{54C6}' - . '\x{54C7}\x{54C8}\x{54C9}\x{54CA}\x{54CB}\x{54CC}\x{54CD}\x{54CE}\x{54CF}' - . '\x{54D0}\x{54D1}\x{54D2}\x{54D3}\x{54D4}\x{54D5}\x{54D6}\x{54D7}\x{54D8}' - . '\x{54D9}\x{54DA}\x{54DB}\x{54DC}\x{54DD}\x{54DE}\x{54DF}\x{54E0}\x{54E1}' - . '\x{54E2}\x{54E3}\x{54E4}\x{54E5}\x{54E6}\x{54E7}\x{54E8}\x{54E9}\x{54EA}' - . '\x{54EB}\x{54EC}\x{54ED}\x{54EE}\x{54EF}\x{54F0}\x{54F1}\x{54F2}\x{54F3}' - . '\x{54F4}\x{54F5}\x{54F7}\x{54F8}\x{54F9}\x{54FA}\x{54FB}\x{54FC}\x{54FD}' - . '\x{54FE}\x{54FF}\x{5500}\x{5501}\x{5502}\x{5503}\x{5504}\x{5505}\x{5506}' - . '\x{5507}\x{5508}\x{5509}\x{550A}\x{550B}\x{550C}\x{550D}\x{550E}\x{550F}' - . '\x{5510}\x{5511}\x{5512}\x{5513}\x{5514}\x{5516}\x{5517}\x{551A}\x{551B}' - . '\x{551C}\x{551D}\x{551E}\x{551F}\x{5520}\x{5521}\x{5522}\x{5523}\x{5524}' - . '\x{5525}\x{5526}\x{5527}\x{5528}\x{5529}\x{552A}\x{552B}\x{552C}\x{552D}' - . '\x{552E}\x{552F}\x{5530}\x{5531}\x{5532}\x{5533}\x{5534}\x{5535}\x{5536}' - . '\x{5537}\x{5538}\x{5539}\x{553A}\x{553B}\x{553C}\x{553D}\x{553E}\x{553F}' - . '\x{5540}\x{5541}\x{5542}\x{5543}\x{5544}\x{5545}\x{5546}\x{5548}\x{5549}' - . '\x{554A}\x{554B}\x{554C}\x{554D}\x{554E}\x{554F}\x{5550}\x{5551}\x{5552}' - . '\x{5553}\x{5554}\x{5555}\x{5556}\x{5557}\x{5558}\x{5559}\x{555A}\x{555B}' - . '\x{555C}\x{555D}\x{555E}\x{555F}\x{5561}\x{5562}\x{5563}\x{5564}\x{5565}' - . '\x{5566}\x{5567}\x{5568}\x{5569}\x{556A}\x{556B}\x{556C}\x{556D}\x{556E}' - . '\x{556F}\x{5570}\x{5571}\x{5572}\x{5573}\x{5574}\x{5575}\x{5576}\x{5577}' - . '\x{5578}\x{5579}\x{557B}\x{557C}\x{557D}\x{557E}\x{557F}\x{5580}\x{5581}' - . '\x{5582}\x{5583}\x{5584}\x{5585}\x{5586}\x{5587}\x{5588}\x{5589}\x{558A}' - . '\x{558B}\x{558C}\x{558D}\x{558E}\x{558F}\x{5590}\x{5591}\x{5592}\x{5593}' - . '\x{5594}\x{5595}\x{5596}\x{5597}\x{5598}\x{5599}\x{559A}\x{559B}\x{559C}' - . '\x{559D}\x{559E}\x{559F}\x{55A0}\x{55A1}\x{55A2}\x{55A3}\x{55A4}\x{55A5}' - . '\x{55A6}\x{55A7}\x{55A8}\x{55A9}\x{55AA}\x{55AB}\x{55AC}\x{55AD}\x{55AE}' - . '\x{55AF}\x{55B0}\x{55B1}\x{55B2}\x{55B3}\x{55B4}\x{55B5}\x{55B6}\x{55B7}' - . '\x{55B8}\x{55B9}\x{55BA}\x{55BB}\x{55BC}\x{55BD}\x{55BE}\x{55BF}\x{55C0}' - . '\x{55C1}\x{55C2}\x{55C3}\x{55C4}\x{55C5}\x{55C6}\x{55C7}\x{55C8}\x{55C9}' - . '\x{55CA}\x{55CB}\x{55CC}\x{55CD}\x{55CE}\x{55CF}\x{55D0}\x{55D1}\x{55D2}' - . '\x{55D3}\x{55D4}\x{55D5}\x{55D6}\x{55D7}\x{55D8}\x{55D9}\x{55DA}\x{55DB}' - . '\x{55DC}\x{55DD}\x{55DE}\x{55DF}\x{55E1}\x{55E2}\x{55E3}\x{55E4}\x{55E5}' - . '\x{55E6}\x{55E7}\x{55E8}\x{55E9}\x{55EA}\x{55EB}\x{55EC}\x{55ED}\x{55EE}' - . '\x{55EF}\x{55F0}\x{55F1}\x{55F2}\x{55F3}\x{55F4}\x{55F5}\x{55F6}\x{55F7}' - . '\x{55F9}\x{55FA}\x{55FB}\x{55FC}\x{55FD}\x{55FE}\x{55FF}\x{5600}\x{5601}' - . '\x{5602}\x{5603}\x{5604}\x{5606}\x{5607}\x{5608}\x{5609}\x{560C}\x{560D}' - . '\x{560E}\x{560F}\x{5610}\x{5611}\x{5612}\x{5613}\x{5614}\x{5615}\x{5616}' - . '\x{5617}\x{5618}\x{5619}\x{561A}\x{561B}\x{561C}\x{561D}\x{561E}\x{561F}' - . '\x{5621}\x{5622}\x{5623}\x{5624}\x{5625}\x{5626}\x{5627}\x{5628}\x{5629}' - . '\x{562A}\x{562C}\x{562D}\x{562E}\x{562F}\x{5630}\x{5631}\x{5632}\x{5633}' - . '\x{5634}\x{5635}\x{5636}\x{5638}\x{5639}\x{563A}\x{563B}\x{563D}\x{563E}' - . '\x{563F}\x{5640}\x{5641}\x{5642}\x{5643}\x{5645}\x{5646}\x{5647}\x{5648}' - . '\x{5649}\x{564A}\x{564C}\x{564D}\x{564E}\x{564F}\x{5650}\x{5652}\x{5653}' - . '\x{5654}\x{5655}\x{5657}\x{5658}\x{5659}\x{565A}\x{565B}\x{565C}\x{565D}' - . '\x{565E}\x{5660}\x{5662}\x{5663}\x{5664}\x{5665}\x{5666}\x{5667}\x{5668}' - . '\x{5669}\x{566A}\x{566B}\x{566C}\x{566D}\x{566E}\x{566F}\x{5670}\x{5671}' - . '\x{5672}\x{5673}\x{5674}\x{5676}\x{5677}\x{5678}\x{5679}\x{567A}\x{567B}' - . '\x{567C}\x{567E}\x{567F}\x{5680}\x{5681}\x{5682}\x{5683}\x{5684}\x{5685}' - . '\x{5686}\x{5687}\x{568A}\x{568C}\x{568D}\x{568E}\x{568F}\x{5690}\x{5691}' - . '\x{5692}\x{5693}\x{5694}\x{5695}\x{5697}\x{5698}\x{5699}\x{569A}\x{569B}' - . '\x{569C}\x{569D}\x{569F}\x{56A0}\x{56A1}\x{56A3}\x{56A4}\x{56A5}\x{56A6}' - . '\x{56A7}\x{56A8}\x{56A9}\x{56AA}\x{56AB}\x{56AC}\x{56AD}\x{56AE}\x{56AF}' - . '\x{56B0}\x{56B1}\x{56B2}\x{56B3}\x{56B4}\x{56B5}\x{56B6}\x{56B7}\x{56B8}' - . '\x{56B9}\x{56BB}\x{56BC}\x{56BD}\x{56BE}\x{56BF}\x{56C0}\x{56C1}\x{56C2}' - . '\x{56C3}\x{56C4}\x{56C5}\x{56C6}\x{56C7}\x{56C8}\x{56C9}\x{56CA}\x{56CB}' - . '\x{56CC}\x{56CD}\x{56CE}\x{56D0}\x{56D1}\x{56D2}\x{56D3}\x{56D4}\x{56D5}' - . '\x{56D6}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DC}\x{56DD}\x{56DE}\x{56DF}' - . '\x{56E0}\x{56E1}\x{56E2}\x{56E3}\x{56E4}\x{56E5}\x{56E7}\x{56E8}\x{56E9}' - . '\x{56EA}\x{56EB}\x{56EC}\x{56ED}\x{56EE}\x{56EF}\x{56F0}\x{56F1}\x{56F2}' - . '\x{56F3}\x{56F4}\x{56F5}\x{56F7}\x{56F9}\x{56FA}\x{56FD}\x{56FE}\x{56FF}' - . '\x{5700}\x{5701}\x{5702}\x{5703}\x{5704}\x{5706}\x{5707}\x{5708}\x{5709}' - . '\x{570A}\x{570B}\x{570C}\x{570D}\x{570E}\x{570F}\x{5710}\x{5712}\x{5713}' - . '\x{5714}\x{5715}\x{5716}\x{5718}\x{5719}\x{571A}\x{571B}\x{571C}\x{571D}' - . '\x{571E}\x{571F}\x{5720}\x{5722}\x{5723}\x{5725}\x{5726}\x{5727}\x{5728}' - . '\x{5729}\x{572A}\x{572B}\x{572C}\x{572D}\x{572E}\x{572F}\x{5730}\x{5731}' - . '\x{5732}\x{5733}\x{5734}\x{5735}\x{5736}\x{5737}\x{5738}\x{5739}\x{573A}' - . '\x{573B}\x{573C}\x{573E}\x{573F}\x{5740}\x{5741}\x{5742}\x{5744}\x{5745}' - . '\x{5746}\x{5747}\x{5749}\x{574A}\x{574B}\x{574C}\x{574D}\x{574E}\x{574F}' - . '\x{5750}\x{5751}\x{5752}\x{5753}\x{5754}\x{5757}\x{5759}\x{575A}\x{575B}' - . '\x{575C}\x{575D}\x{575E}\x{575F}\x{5760}\x{5761}\x{5762}\x{5764}\x{5765}' - . '\x{5766}\x{5767}\x{5768}\x{5769}\x{576A}\x{576B}\x{576C}\x{576D}\x{576F}' - . '\x{5770}\x{5771}\x{5772}\x{5773}\x{5774}\x{5775}\x{5776}\x{5777}\x{5779}' - . '\x{577A}\x{577B}\x{577C}\x{577D}\x{577E}\x{577F}\x{5780}\x{5782}\x{5783}' - . '\x{5784}\x{5785}\x{5786}\x{5788}\x{5789}\x{578A}\x{578B}\x{578C}\x{578D}' - . '\x{578E}\x{578F}\x{5790}\x{5791}\x{5792}\x{5793}\x{5794}\x{5795}\x{5797}' - . '\x{5798}\x{5799}\x{579A}\x{579B}\x{579C}\x{579D}\x{579E}\x{579F}\x{57A0}' - . '\x{57A1}\x{57A2}\x{57A3}\x{57A4}\x{57A5}\x{57A6}\x{57A7}\x{57A9}\x{57AA}' - . '\x{57AB}\x{57AC}\x{57AD}\x{57AE}\x{57AF}\x{57B0}\x{57B1}\x{57B2}\x{57B3}' - . '\x{57B4}\x{57B5}\x{57B6}\x{57B7}\x{57B8}\x{57B9}\x{57BA}\x{57BB}\x{57BC}' - . '\x{57BD}\x{57BE}\x{57BF}\x{57C0}\x{57C1}\x{57C2}\x{57C3}\x{57C4}\x{57C5}' - . '\x{57C6}\x{57C7}\x{57C8}\x{57C9}\x{57CB}\x{57CC}\x{57CD}\x{57CE}\x{57CF}' - . '\x{57D0}\x{57D2}\x{57D3}\x{57D4}\x{57D5}\x{57D6}\x{57D8}\x{57D9}\x{57DA}' - . '\x{57DC}\x{57DD}\x{57DF}\x{57E0}\x{57E1}\x{57E2}\x{57E3}\x{57E4}\x{57E5}' - . '\x{57E6}\x{57E7}\x{57E8}\x{57E9}\x{57EA}\x{57EB}\x{57EC}\x{57ED}\x{57EE}' - . '\x{57EF}\x{57F0}\x{57F1}\x{57F2}\x{57F3}\x{57F4}\x{57F5}\x{57F6}\x{57F7}' - . '\x{57F8}\x{57F9}\x{57FA}\x{57FB}\x{57FC}\x{57FD}\x{57FE}\x{57FF}\x{5800}' - . '\x{5801}\x{5802}\x{5803}\x{5804}\x{5805}\x{5806}\x{5807}\x{5808}\x{5809}' - . '\x{580A}\x{580B}\x{580C}\x{580D}\x{580E}\x{580F}\x{5810}\x{5811}\x{5812}' - . '\x{5813}\x{5814}\x{5815}\x{5816}\x{5819}\x{581A}\x{581B}\x{581C}\x{581D}' - . '\x{581E}\x{581F}\x{5820}\x{5821}\x{5822}\x{5823}\x{5824}\x{5825}\x{5826}' - . '\x{5827}\x{5828}\x{5829}\x{582A}\x{582B}\x{582C}\x{582D}\x{582E}\x{582F}' - . '\x{5830}\x{5831}\x{5832}\x{5833}\x{5834}\x{5835}\x{5836}\x{5837}\x{5838}' - . '\x{5839}\x{583A}\x{583B}\x{583C}\x{583D}\x{583E}\x{583F}\x{5840}\x{5842}' - . '\x{5843}\x{5844}\x{5845}\x{5846}\x{5847}\x{5848}\x{5849}\x{584A}\x{584B}' - . '\x{584C}\x{584D}\x{584E}\x{584F}\x{5851}\x{5852}\x{5853}\x{5854}\x{5855}' - . '\x{5857}\x{5858}\x{5859}\x{585A}\x{585B}\x{585C}\x{585D}\x{585E}\x{585F}' - . '\x{5861}\x{5862}\x{5863}\x{5864}\x{5865}\x{5868}\x{5869}\x{586A}\x{586B}' - . '\x{586C}\x{586D}\x{586E}\x{586F}\x{5870}\x{5871}\x{5872}\x{5873}\x{5874}' - . '\x{5875}\x{5876}\x{5878}\x{5879}\x{587A}\x{587B}\x{587C}\x{587D}\x{587E}' - . '\x{587F}\x{5880}\x{5881}\x{5882}\x{5883}\x{5884}\x{5885}\x{5886}\x{5887}' - . '\x{5888}\x{5889}\x{588A}\x{588B}\x{588C}\x{588D}\x{588E}\x{588F}\x{5890}' - . '\x{5891}\x{5892}\x{5893}\x{5894}\x{5896}\x{5897}\x{5898}\x{5899}\x{589A}' - . '\x{589B}\x{589C}\x{589D}\x{589E}\x{589F}\x{58A0}\x{58A1}\x{58A2}\x{58A3}' - . '\x{58A4}\x{58A5}\x{58A6}\x{58A7}\x{58A8}\x{58A9}\x{58AB}\x{58AC}\x{58AD}' - . '\x{58AE}\x{58AF}\x{58B0}\x{58B1}\x{58B2}\x{58B3}\x{58B4}\x{58B7}\x{58B8}' - . '\x{58B9}\x{58BA}\x{58BB}\x{58BC}\x{58BD}\x{58BE}\x{58BF}\x{58C1}\x{58C2}' - . '\x{58C5}\x{58C6}\x{58C7}\x{58C8}\x{58C9}\x{58CA}\x{58CB}\x{58CE}\x{58CF}' - . '\x{58D1}\x{58D2}\x{58D3}\x{58D4}\x{58D5}\x{58D6}\x{58D7}\x{58D8}\x{58D9}' - . '\x{58DA}\x{58DB}\x{58DD}\x{58DE}\x{58DF}\x{58E0}\x{58E2}\x{58E3}\x{58E4}' - . '\x{58E5}\x{58E7}\x{58E8}\x{58E9}\x{58EA}\x{58EB}\x{58EC}\x{58ED}\x{58EE}' - . '\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F3}\x{58F4}\x{58F6}\x{58F7}\x{58F8}' - . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{58FE}\x{58FF}\x{5900}\x{5902}' - . '\x{5903}\x{5904}\x{5906}\x{5907}\x{5909}\x{590A}\x{590B}\x{590C}\x{590D}' - . '\x{590E}\x{590F}\x{5910}\x{5912}\x{5914}\x{5915}\x{5916}\x{5917}\x{5918}' - . '\x{5919}\x{591A}\x{591B}\x{591C}\x{591D}\x{591E}\x{591F}\x{5920}\x{5921}' - . '\x{5922}\x{5924}\x{5925}\x{5926}\x{5927}\x{5928}\x{5929}\x{592A}\x{592B}' - . '\x{592C}\x{592D}\x{592E}\x{592F}\x{5930}\x{5931}\x{5932}\x{5934}\x{5935}' - . '\x{5937}\x{5938}\x{5939}\x{593A}\x{593B}\x{593C}\x{593D}\x{593E}\x{593F}' - . '\x{5940}\x{5941}\x{5942}\x{5943}\x{5944}\x{5945}\x{5946}\x{5947}\x{5948}' - . '\x{5949}\x{594A}\x{594B}\x{594C}\x{594D}\x{594E}\x{594F}\x{5950}\x{5951}' - . '\x{5952}\x{5953}\x{5954}\x{5955}\x{5956}\x{5957}\x{5958}\x{595A}\x{595C}' - . '\x{595D}\x{595E}\x{595F}\x{5960}\x{5961}\x{5962}\x{5963}\x{5964}\x{5965}' - . '\x{5966}\x{5967}\x{5968}\x{5969}\x{596A}\x{596B}\x{596C}\x{596D}\x{596E}' - . '\x{596F}\x{5970}\x{5971}\x{5972}\x{5973}\x{5974}\x{5975}\x{5976}\x{5977}' - . '\x{5978}\x{5979}\x{597A}\x{597B}\x{597C}\x{597D}\x{597E}\x{597F}\x{5980}' - . '\x{5981}\x{5982}\x{5983}\x{5984}\x{5985}\x{5986}\x{5987}\x{5988}\x{5989}' - . '\x{598A}\x{598B}\x{598C}\x{598D}\x{598E}\x{598F}\x{5990}\x{5991}\x{5992}' - . '\x{5993}\x{5994}\x{5995}\x{5996}\x{5997}\x{5998}\x{5999}\x{599A}\x{599C}' - . '\x{599D}\x{599E}\x{599F}\x{59A0}\x{59A1}\x{59A2}\x{59A3}\x{59A4}\x{59A5}' - . '\x{59A6}\x{59A7}\x{59A8}\x{59A9}\x{59AA}\x{59AB}\x{59AC}\x{59AD}\x{59AE}' - . '\x{59AF}\x{59B0}\x{59B1}\x{59B2}\x{59B3}\x{59B4}\x{59B5}\x{59B6}\x{59B8}' - . '\x{59B9}\x{59BA}\x{59BB}\x{59BC}\x{59BD}\x{59BE}\x{59BF}\x{59C0}\x{59C1}' - . '\x{59C2}\x{59C3}\x{59C4}\x{59C5}\x{59C6}\x{59C7}\x{59C8}\x{59C9}\x{59CA}' - . '\x{59CB}\x{59CC}\x{59CD}\x{59CE}\x{59CF}\x{59D0}\x{59D1}\x{59D2}\x{59D3}' - . '\x{59D4}\x{59D5}\x{59D6}\x{59D7}\x{59D8}\x{59D9}\x{59DA}\x{59DB}\x{59DC}' - . '\x{59DD}\x{59DE}\x{59DF}\x{59E0}\x{59E1}\x{59E2}\x{59E3}\x{59E4}\x{59E5}' - . '\x{59E6}\x{59E8}\x{59E9}\x{59EA}\x{59EB}\x{59EC}\x{59ED}\x{59EE}\x{59EF}' - . '\x{59F0}\x{59F1}\x{59F2}\x{59F3}\x{59F4}\x{59F5}\x{59F6}\x{59F7}\x{59F8}' - . '\x{59F9}\x{59FA}\x{59FB}\x{59FC}\x{59FD}\x{59FE}\x{59FF}\x{5A00}\x{5A01}' - . '\x{5A02}\x{5A03}\x{5A04}\x{5A05}\x{5A06}\x{5A07}\x{5A08}\x{5A09}\x{5A0A}' - . '\x{5A0B}\x{5A0C}\x{5A0D}\x{5A0E}\x{5A0F}\x{5A10}\x{5A11}\x{5A12}\x{5A13}' - . '\x{5A14}\x{5A15}\x{5A16}\x{5A17}\x{5A18}\x{5A19}\x{5A1A}\x{5A1B}\x{5A1C}' - . '\x{5A1D}\x{5A1E}\x{5A1F}\x{5A20}\x{5A21}\x{5A22}\x{5A23}\x{5A25}\x{5A27}' - . '\x{5A28}\x{5A29}\x{5A2A}\x{5A2B}\x{5A2D}\x{5A2E}\x{5A2F}\x{5A31}\x{5A32}' - . '\x{5A33}\x{5A34}\x{5A35}\x{5A36}\x{5A37}\x{5A38}\x{5A39}\x{5A3A}\x{5A3B}' - . '\x{5A3C}\x{5A3D}\x{5A3E}\x{5A3F}\x{5A40}\x{5A41}\x{5A42}\x{5A43}\x{5A44}' - . '\x{5A45}\x{5A46}\x{5A47}\x{5A48}\x{5A49}\x{5A4A}\x{5A4B}\x{5A4C}\x{5A4D}' - . '\x{5A4E}\x{5A4F}\x{5A50}\x{5A51}\x{5A52}\x{5A53}\x{5A55}\x{5A56}\x{5A57}' - . '\x{5A58}\x{5A5A}\x{5A5B}\x{5A5C}\x{5A5D}\x{5A5E}\x{5A5F}\x{5A60}\x{5A61}' - . '\x{5A62}\x{5A63}\x{5A64}\x{5A65}\x{5A66}\x{5A67}\x{5A68}\x{5A69}\x{5A6A}' - . '\x{5A6B}\x{5A6C}\x{5A6D}\x{5A6E}\x{5A70}\x{5A72}\x{5A73}\x{5A74}\x{5A75}' - . '\x{5A76}\x{5A77}\x{5A78}\x{5A79}\x{5A7A}\x{5A7B}\x{5A7C}\x{5A7D}\x{5A7E}' - . '\x{5A7F}\x{5A80}\x{5A81}\x{5A82}\x{5A83}\x{5A84}\x{5A85}\x{5A86}\x{5A88}' - . '\x{5A89}\x{5A8A}\x{5A8B}\x{5A8C}\x{5A8E}\x{5A8F}\x{5A90}\x{5A91}\x{5A92}' - . '\x{5A93}\x{5A94}\x{5A95}\x{5A96}\x{5A97}\x{5A98}\x{5A99}\x{5A9A}\x{5A9B}' - . '\x{5A9C}\x{5A9D}\x{5A9E}\x{5A9F}\x{5AA0}\x{5AA1}\x{5AA2}\x{5AA3}\x{5AA4}' - . '\x{5AA5}\x{5AA6}\x{5AA7}\x{5AA8}\x{5AA9}\x{5AAA}\x{5AAC}\x{5AAD}\x{5AAE}' - . '\x{5AAF}\x{5AB0}\x{5AB1}\x{5AB2}\x{5AB3}\x{5AB4}\x{5AB5}\x{5AB6}\x{5AB7}' - . '\x{5AB8}\x{5AB9}\x{5ABA}\x{5ABB}\x{5ABC}\x{5ABD}\x{5ABE}\x{5ABF}\x{5AC0}' - . '\x{5AC1}\x{5AC2}\x{5AC3}\x{5AC4}\x{5AC5}\x{5AC6}\x{5AC7}\x{5AC8}\x{5AC9}' - . '\x{5ACA}\x{5ACB}\x{5ACC}\x{5ACD}\x{5ACE}\x{5ACF}\x{5AD1}\x{5AD2}\x{5AD4}' - . '\x{5AD5}\x{5AD6}\x{5AD7}\x{5AD8}\x{5AD9}\x{5ADA}\x{5ADB}\x{5ADC}\x{5ADD}' - . '\x{5ADE}\x{5ADF}\x{5AE0}\x{5AE1}\x{5AE2}\x{5AE3}\x{5AE4}\x{5AE5}\x{5AE6}' - . '\x{5AE7}\x{5AE8}\x{5AE9}\x{5AEA}\x{5AEB}\x{5AEC}\x{5AED}\x{5AEE}\x{5AF1}' - . '\x{5AF2}\x{5AF3}\x{5AF4}\x{5AF5}\x{5AF6}\x{5AF7}\x{5AF8}\x{5AF9}\x{5AFA}' - . '\x{5AFB}\x{5AFC}\x{5AFD}\x{5AFE}\x{5AFF}\x{5B00}\x{5B01}\x{5B02}\x{5B03}' - . '\x{5B04}\x{5B05}\x{5B06}\x{5B07}\x{5B08}\x{5B09}\x{5B0B}\x{5B0C}\x{5B0E}' - . '\x{5B0F}\x{5B10}\x{5B11}\x{5B12}\x{5B13}\x{5B14}\x{5B15}\x{5B16}\x{5B17}' - . '\x{5B18}\x{5B19}\x{5B1A}\x{5B1B}\x{5B1C}\x{5B1D}\x{5B1E}\x{5B1F}\x{5B20}' - . '\x{5B21}\x{5B22}\x{5B23}\x{5B24}\x{5B25}\x{5B26}\x{5B27}\x{5B28}\x{5B29}' - . '\x{5B2A}\x{5B2B}\x{5B2C}\x{5B2D}\x{5B2E}\x{5B2F}\x{5B30}\x{5B31}\x{5B32}' - . '\x{5B33}\x{5B34}\x{5B35}\x{5B36}\x{5B37}\x{5B38}\x{5B3A}\x{5B3B}\x{5B3C}' - . '\x{5B3D}\x{5B3E}\x{5B3F}\x{5B40}\x{5B41}\x{5B42}\x{5B43}\x{5B44}\x{5B45}' - . '\x{5B47}\x{5B48}\x{5B49}\x{5B4A}\x{5B4B}\x{5B4C}\x{5B4D}\x{5B4E}\x{5B50}' - . '\x{5B51}\x{5B53}\x{5B54}\x{5B55}\x{5B56}\x{5B57}\x{5B58}\x{5B59}\x{5B5A}' - . '\x{5B5B}\x{5B5C}\x{5B5D}\x{5B5E}\x{5B5F}\x{5B62}\x{5B63}\x{5B64}\x{5B65}' - . '\x{5B66}\x{5B67}\x{5B68}\x{5B69}\x{5B6A}\x{5B6B}\x{5B6C}\x{5B6D}\x{5B6E}' - . '\x{5B70}\x{5B71}\x{5B72}\x{5B73}\x{5B74}\x{5B75}\x{5B76}\x{5B77}\x{5B78}' - . '\x{5B7A}\x{5B7B}\x{5B7C}\x{5B7D}\x{5B7F}\x{5B80}\x{5B81}\x{5B82}\x{5B83}' - . '\x{5B84}\x{5B85}\x{5B87}\x{5B88}\x{5B89}\x{5B8A}\x{5B8B}\x{5B8C}\x{5B8D}' - . '\x{5B8E}\x{5B8F}\x{5B91}\x{5B92}\x{5B93}\x{5B94}\x{5B95}\x{5B96}\x{5B97}' - . '\x{5B98}\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9E}\x{5B9F}\x{5BA0}' - . '\x{5BA1}\x{5BA2}\x{5BA3}\x{5BA4}\x{5BA5}\x{5BA6}\x{5BA7}\x{5BA8}\x{5BAA}' - . '\x{5BAB}\x{5BAC}\x{5BAD}\x{5BAE}\x{5BAF}\x{5BB0}\x{5BB1}\x{5BB3}\x{5BB4}' - . '\x{5BB5}\x{5BB6}\x{5BB8}\x{5BB9}\x{5BBA}\x{5BBB}\x{5BBD}\x{5BBE}\x{5BBF}' - . '\x{5BC0}\x{5BC1}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BCA}' - . '\x{5BCB}\x{5BCC}\x{5BCD}\x{5BCE}\x{5BCF}\x{5BD0}\x{5BD1}\x{5BD2}\x{5BD3}' - . '\x{5BD4}\x{5BD5}\x{5BD6}\x{5BD8}\x{5BD9}\x{5BDB}\x{5BDC}\x{5BDD}\x{5BDE}' - . '\x{5BDF}\x{5BE0}\x{5BE1}\x{5BE2}\x{5BE3}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}' - . '\x{5BE8}\x{5BE9}\x{5BEA}\x{5BEB}\x{5BEC}\x{5BED}\x{5BEE}\x{5BEF}\x{5BF0}' - . '\x{5BF1}\x{5BF2}\x{5BF3}\x{5BF4}\x{5BF5}\x{5BF6}\x{5BF7}\x{5BF8}\x{5BF9}' - . '\x{5BFA}\x{5BFB}\x{5BFC}\x{5BFD}\x{5BFF}\x{5C01}\x{5C03}\x{5C04}\x{5C05}' - . '\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}\x{5C0B}\x{5C0C}\x{5C0D}\x{5C0E}' - . '\x{5C0F}\x{5C10}\x{5C11}\x{5C12}\x{5C13}\x{5C14}\x{5C15}\x{5C16}\x{5C17}' - . '\x{5C18}\x{5C19}\x{5C1A}\x{5C1C}\x{5C1D}\x{5C1E}\x{5C1F}\x{5C20}\x{5C21}' - . '\x{5C22}\x{5C24}\x{5C25}\x{5C27}\x{5C28}\x{5C2A}\x{5C2B}\x{5C2C}\x{5C2D}' - . '\x{5C2E}\x{5C2F}\x{5C30}\x{5C31}\x{5C32}\x{5C33}\x{5C34}\x{5C35}\x{5C37}' - . '\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}' - . '\x{5C41}\x{5C42}\x{5C43}\x{5C44}\x{5C45}\x{5C46}\x{5C47}\x{5C48}\x{5C49}' - . '\x{5C4A}\x{5C4B}\x{5C4C}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C52}' - . '\x{5C53}\x{5C54}\x{5C55}\x{5C56}\x{5C57}\x{5C58}\x{5C59}\x{5C5B}\x{5C5C}' - . '\x{5C5D}\x{5C5E}\x{5C5F}\x{5C60}\x{5C61}\x{5C62}\x{5C63}\x{5C64}\x{5C65}' - . '\x{5C66}\x{5C67}\x{5C68}\x{5C69}\x{5C6A}\x{5C6B}\x{5C6C}\x{5C6D}\x{5C6E}' - . '\x{5C6F}\x{5C70}\x{5C71}\x{5C72}\x{5C73}\x{5C74}\x{5C75}\x{5C76}\x{5C77}' - . '\x{5C78}\x{5C79}\x{5C7A}\x{5C7B}\x{5C7C}\x{5C7D}\x{5C7E}\x{5C7F}\x{5C80}' - . '\x{5C81}\x{5C82}\x{5C83}\x{5C84}\x{5C86}\x{5C87}\x{5C88}\x{5C89}\x{5C8A}' - . '\x{5C8B}\x{5C8C}\x{5C8D}\x{5C8E}\x{5C8F}\x{5C90}\x{5C91}\x{5C92}\x{5C93}' - . '\x{5C94}\x{5C95}\x{5C96}\x{5C97}\x{5C98}\x{5C99}\x{5C9A}\x{5C9B}\x{5C9C}' - . '\x{5C9D}\x{5C9E}\x{5C9F}\x{5CA0}\x{5CA1}\x{5CA2}\x{5CA3}\x{5CA4}\x{5CA5}' - . '\x{5CA6}\x{5CA7}\x{5CA8}\x{5CA9}\x{5CAA}\x{5CAB}\x{5CAC}\x{5CAD}\x{5CAE}' - . '\x{5CAF}\x{5CB0}\x{5CB1}\x{5CB2}\x{5CB3}\x{5CB5}\x{5CB6}\x{5CB7}\x{5CB8}' - . '\x{5CBA}\x{5CBB}\x{5CBC}\x{5CBD}\x{5CBE}\x{5CBF}\x{5CC1}\x{5CC2}\x{5CC3}' - . '\x{5CC4}\x{5CC5}\x{5CC6}\x{5CC7}\x{5CC8}\x{5CC9}\x{5CCA}\x{5CCB}\x{5CCC}' - . '\x{5CCD}\x{5CCE}\x{5CCF}\x{5CD0}\x{5CD1}\x{5CD2}\x{5CD3}\x{5CD4}\x{5CD6}' - . '\x{5CD7}\x{5CD8}\x{5CD9}\x{5CDA}\x{5CDB}\x{5CDC}\x{5CDE}\x{5CDF}\x{5CE0}' - . '\x{5CE1}\x{5CE2}\x{5CE3}\x{5CE4}\x{5CE5}\x{5CE6}\x{5CE7}\x{5CE8}\x{5CE9}' - . '\x{5CEA}\x{5CEB}\x{5CEC}\x{5CED}\x{5CEE}\x{5CEF}\x{5CF0}\x{5CF1}\x{5CF2}' - . '\x{5CF3}\x{5CF4}\x{5CF6}\x{5CF7}\x{5CF8}\x{5CF9}\x{5CFA}\x{5CFB}\x{5CFC}' - . '\x{5CFD}\x{5CFE}\x{5CFF}\x{5D00}\x{5D01}\x{5D02}\x{5D03}\x{5D04}\x{5D05}' - . '\x{5D06}\x{5D07}\x{5D08}\x{5D09}\x{5D0A}\x{5D0B}\x{5D0C}\x{5D0D}\x{5D0E}' - . '\x{5D0F}\x{5D10}\x{5D11}\x{5D12}\x{5D13}\x{5D14}\x{5D15}\x{5D16}\x{5D17}' - . '\x{5D18}\x{5D19}\x{5D1A}\x{5D1B}\x{5D1C}\x{5D1D}\x{5D1E}\x{5D1F}\x{5D20}' - . '\x{5D21}\x{5D22}\x{5D23}\x{5D24}\x{5D25}\x{5D26}\x{5D27}\x{5D28}\x{5D29}' - . '\x{5D2A}\x{5D2C}\x{5D2D}\x{5D2E}\x{5D30}\x{5D31}\x{5D32}\x{5D33}\x{5D34}' - . '\x{5D35}\x{5D36}\x{5D37}\x{5D38}\x{5D39}\x{5D3A}\x{5D3C}\x{5D3D}\x{5D3E}' - . '\x{5D3F}\x{5D40}\x{5D41}\x{5D42}\x{5D43}\x{5D44}\x{5D45}\x{5D46}\x{5D47}' - . '\x{5D48}\x{5D49}\x{5D4A}\x{5D4B}\x{5D4C}\x{5D4D}\x{5D4E}\x{5D4F}\x{5D50}' - . '\x{5D51}\x{5D52}\x{5D54}\x{5D55}\x{5D56}\x{5D58}\x{5D59}\x{5D5A}\x{5D5B}' - . '\x{5D5D}\x{5D5E}\x{5D5F}\x{5D61}\x{5D62}\x{5D63}\x{5D64}\x{5D65}\x{5D66}' - . '\x{5D67}\x{5D68}\x{5D69}\x{5D6A}\x{5D6B}\x{5D6C}\x{5D6D}\x{5D6E}\x{5D6F}' - . '\x{5D70}\x{5D71}\x{5D72}\x{5D73}\x{5D74}\x{5D75}\x{5D76}\x{5D77}\x{5D78}' - . '\x{5D79}\x{5D7A}\x{5D7B}\x{5D7C}\x{5D7D}\x{5D7E}\x{5D7F}\x{5D80}\x{5D81}' - . '\x{5D82}\x{5D84}\x{5D85}\x{5D86}\x{5D87}\x{5D88}\x{5D89}\x{5D8A}\x{5D8B}' - . '\x{5D8C}\x{5D8D}\x{5D8E}\x{5D8F}\x{5D90}\x{5D91}\x{5D92}\x{5D93}\x{5D94}' - . '\x{5D95}\x{5D97}\x{5D98}\x{5D99}\x{5D9A}\x{5D9B}\x{5D9C}\x{5D9D}\x{5D9E}' - . '\x{5D9F}\x{5DA0}\x{5DA1}\x{5DA2}\x{5DA5}\x{5DA6}\x{5DA7}\x{5DA8}\x{5DA9}' - . '\x{5DAA}\x{5DAC}\x{5DAD}\x{5DAE}\x{5DAF}\x{5DB0}\x{5DB1}\x{5DB2}\x{5DB4}' - . '\x{5DB5}\x{5DB6}\x{5DB7}\x{5DB8}\x{5DBA}\x{5DBB}\x{5DBC}\x{5DBD}\x{5DBE}' - . '\x{5DBF}\x{5DC0}\x{5DC1}\x{5DC2}\x{5DC3}\x{5DC5}\x{5DC6}\x{5DC7}\x{5DC8}' - . '\x{5DC9}\x{5DCA}\x{5DCB}\x{5DCC}\x{5DCD}\x{5DCE}\x{5DCF}\x{5DD0}\x{5DD1}' - . '\x{5DD2}\x{5DD3}\x{5DD4}\x{5DD5}\x{5DD6}\x{5DD8}\x{5DD9}\x{5DDB}\x{5DDD}' - . '\x{5DDE}\x{5DDF}\x{5DE0}\x{5DE1}\x{5DE2}\x{5DE3}\x{5DE4}\x{5DE5}\x{5DE6}' - . '\x{5DE7}\x{5DE8}\x{5DE9}\x{5DEA}\x{5DEB}\x{5DEC}\x{5DED}\x{5DEE}\x{5DEF}' - . '\x{5DF0}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DF8}\x{5DF9}' - . '\x{5DFA}\x{5DFB}\x{5DFC}\x{5DFD}\x{5DFE}\x{5DFF}\x{5E00}\x{5E01}\x{5E02}' - . '\x{5E03}\x{5E04}\x{5E05}\x{5E06}\x{5E07}\x{5E08}\x{5E09}\x{5E0A}\x{5E0B}' - . '\x{5E0C}\x{5E0D}\x{5E0E}\x{5E0F}\x{5E10}\x{5E11}\x{5E13}\x{5E14}\x{5E15}' - . '\x{5E16}\x{5E17}\x{5E18}\x{5E19}\x{5E1A}\x{5E1B}\x{5E1C}\x{5E1D}\x{5E1E}' - . '\x{5E1F}\x{5E20}\x{5E21}\x{5E22}\x{5E23}\x{5E24}\x{5E25}\x{5E26}\x{5E27}' - . '\x{5E28}\x{5E29}\x{5E2A}\x{5E2B}\x{5E2C}\x{5E2D}\x{5E2E}\x{5E2F}\x{5E30}' - . '\x{5E31}\x{5E32}\x{5E33}\x{5E34}\x{5E35}\x{5E36}\x{5E37}\x{5E38}\x{5E39}' - . '\x{5E3A}\x{5E3B}\x{5E3C}\x{5E3D}\x{5E3E}\x{5E40}\x{5E41}\x{5E42}\x{5E43}' - . '\x{5E44}\x{5E45}\x{5E46}\x{5E47}\x{5E49}\x{5E4A}\x{5E4B}\x{5E4C}\x{5E4D}' - . '\x{5E4E}\x{5E4F}\x{5E50}\x{5E52}\x{5E53}\x{5E54}\x{5E55}\x{5E56}\x{5E57}' - . '\x{5E58}\x{5E59}\x{5E5A}\x{5E5B}\x{5E5C}\x{5E5D}\x{5E5E}\x{5E5F}\x{5E60}' - . '\x{5E61}\x{5E62}\x{5E63}\x{5E64}\x{5E65}\x{5E66}\x{5E67}\x{5E68}\x{5E69}' - . '\x{5E6A}\x{5E6B}\x{5E6C}\x{5E6D}\x{5E6E}\x{5E6F}\x{5E70}\x{5E71}\x{5E72}' - . '\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E77}\x{5E78}\x{5E79}\x{5E7A}\x{5E7B}' - . '\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E80}\x{5E81}\x{5E82}\x{5E83}\x{5E84}' - . '\x{5E85}\x{5E86}\x{5E87}\x{5E88}\x{5E89}\x{5E8A}\x{5E8B}\x{5E8C}\x{5E8D}' - . '\x{5E8E}\x{5E8F}\x{5E90}\x{5E91}\x{5E93}\x{5E94}\x{5E95}\x{5E96}\x{5E97}' - . '\x{5E98}\x{5E99}\x{5E9A}\x{5E9B}\x{5E9C}\x{5E9D}\x{5E9E}\x{5E9F}\x{5EA0}' - . '\x{5EA1}\x{5EA2}\x{5EA3}\x{5EA4}\x{5EA5}\x{5EA6}\x{5EA7}\x{5EA8}\x{5EA9}' - . '\x{5EAA}\x{5EAB}\x{5EAC}\x{5EAD}\x{5EAE}\x{5EAF}\x{5EB0}\x{5EB1}\x{5EB2}' - . '\x{5EB3}\x{5EB4}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EB9}\x{5EBB}\x{5EBC}' - . '\x{5EBD}\x{5EBE}\x{5EBF}\x{5EC1}\x{5EC2}\x{5EC3}\x{5EC4}\x{5EC5}\x{5EC6}' - . '\x{5EC7}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECB}\x{5ECC}\x{5ECD}\x{5ECE}\x{5ECF}' - . '\x{5ED0}\x{5ED1}\x{5ED2}\x{5ED3}\x{5ED4}\x{5ED5}\x{5ED6}\x{5ED7}\x{5ED8}' - . '\x{5ED9}\x{5EDA}\x{5EDB}\x{5EDC}\x{5EDD}\x{5EDE}\x{5EDF}\x{5EE0}\x{5EE1}' - . '\x{5EE2}\x{5EE3}\x{5EE4}\x{5EE5}\x{5EE6}\x{5EE7}\x{5EE8}\x{5EE9}\x{5EEA}' - . '\x{5EEC}\x{5EED}\x{5EEE}\x{5EEF}\x{5EF0}\x{5EF1}\x{5EF2}\x{5EF3}\x{5EF4}' - . '\x{5EF5}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}\x{5EFB}\x{5EFC}\x{5EFD}\x{5EFE}' - . '\x{5EFF}\x{5F00}\x{5F01}\x{5F02}\x{5F03}\x{5F04}\x{5F05}\x{5F06}\x{5F07}' - . '\x{5F08}\x{5F0A}\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F11}\x{5F12}\x{5F13}' - . '\x{5F14}\x{5F15}\x{5F16}\x{5F17}\x{5F18}\x{5F19}\x{5F1A}\x{5F1B}\x{5F1C}' - . '\x{5F1D}\x{5F1E}\x{5F1F}\x{5F20}\x{5F21}\x{5F22}\x{5F23}\x{5F24}\x{5F25}' - . '\x{5F26}\x{5F27}\x{5F28}\x{5F29}\x{5F2A}\x{5F2B}\x{5F2C}\x{5F2D}\x{5F2E}' - . '\x{5F2F}\x{5F30}\x{5F31}\x{5F32}\x{5F33}\x{5F34}\x{5F35}\x{5F36}\x{5F37}' - . '\x{5F38}\x{5F39}\x{5F3A}\x{5F3C}\x{5F3E}\x{5F3F}\x{5F40}\x{5F41}\x{5F42}' - . '\x{5F43}\x{5F44}\x{5F45}\x{5F46}\x{5F47}\x{5F48}\x{5F49}\x{5F4A}\x{5F4B}' - . '\x{5F4C}\x{5F4D}\x{5F4E}\x{5F4F}\x{5F50}\x{5F51}\x{5F52}\x{5F53}\x{5F54}' - . '\x{5F55}\x{5F56}\x{5F57}\x{5F58}\x{5F59}\x{5F5A}\x{5F5B}\x{5F5C}\x{5F5D}' - . '\x{5F5E}\x{5F5F}\x{5F60}\x{5F61}\x{5F62}\x{5F63}\x{5F64}\x{5F65}\x{5F66}' - . '\x{5F67}\x{5F68}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}\x{5F6D}\x{5F6E}\x{5F6F}' - . '\x{5F70}\x{5F71}\x{5F72}\x{5F73}\x{5F74}\x{5F75}\x{5F76}\x{5F77}\x{5F78}' - . '\x{5F79}\x{5F7A}\x{5F7B}\x{5F7C}\x{5F7D}\x{5F7E}\x{5F7F}\x{5F80}\x{5F81}' - . '\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F86}\x{5F87}\x{5F88}\x{5F89}\x{5F8A}' - . '\x{5F8B}\x{5F8C}\x{5F8D}\x{5F8E}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F94}' - . '\x{5F95}\x{5F96}\x{5F97}\x{5F98}\x{5F99}\x{5F9B}\x{5F9C}\x{5F9D}\x{5F9E}' - . '\x{5F9F}\x{5FA0}\x{5FA1}\x{5FA2}\x{5FA5}\x{5FA6}\x{5FA7}\x{5FA8}\x{5FA9}' - . '\x{5FAA}\x{5FAB}\x{5FAC}\x{5FAD}\x{5FAE}\x{5FAF}\x{5FB1}\x{5FB2}\x{5FB3}' - . '\x{5FB4}\x{5FB5}\x{5FB6}\x{5FB7}\x{5FB8}\x{5FB9}\x{5FBA}\x{5FBB}\x{5FBC}' - . '\x{5FBD}\x{5FBE}\x{5FBF}\x{5FC0}\x{5FC1}\x{5FC3}\x{5FC4}\x{5FC5}\x{5FC6}' - . '\x{5FC7}\x{5FC8}\x{5FC9}\x{5FCA}\x{5FCB}\x{5FCC}\x{5FCD}\x{5FCF}\x{5FD0}' - . '\x{5FD1}\x{5FD2}\x{5FD3}\x{5FD4}\x{5FD5}\x{5FD6}\x{5FD7}\x{5FD8}\x{5FD9}' - . '\x{5FDA}\x{5FDC}\x{5FDD}\x{5FDE}\x{5FE0}\x{5FE1}\x{5FE3}\x{5FE4}\x{5FE5}' - . '\x{5FE6}\x{5FE7}\x{5FE8}\x{5FE9}\x{5FEA}\x{5FEB}\x{5FED}\x{5FEE}\x{5FEF}' - . '\x{5FF0}\x{5FF1}\x{5FF2}\x{5FF3}\x{5FF4}\x{5FF5}\x{5FF6}\x{5FF7}\x{5FF8}' - . '\x{5FF9}\x{5FFA}\x{5FFB}\x{5FFD}\x{5FFE}\x{5FFF}\x{6000}\x{6001}\x{6002}' - . '\x{6003}\x{6004}\x{6005}\x{6006}\x{6007}\x{6008}\x{6009}\x{600A}\x{600B}' - . '\x{600C}\x{600D}\x{600E}\x{600F}\x{6010}\x{6011}\x{6012}\x{6013}\x{6014}' - . '\x{6015}\x{6016}\x{6017}\x{6018}\x{6019}\x{601A}\x{601B}\x{601C}\x{601D}' - . '\x{601E}\x{601F}\x{6020}\x{6021}\x{6022}\x{6024}\x{6025}\x{6026}\x{6027}' - . '\x{6028}\x{6029}\x{602A}\x{602B}\x{602C}\x{602D}\x{602E}\x{602F}\x{6030}' - . '\x{6031}\x{6032}\x{6033}\x{6034}\x{6035}\x{6036}\x{6037}\x{6038}\x{6039}' - . '\x{603A}\x{603B}\x{603C}\x{603D}\x{603E}\x{603F}\x{6040}\x{6041}\x{6042}' - . '\x{6043}\x{6044}\x{6045}\x{6046}\x{6047}\x{6048}\x{6049}\x{604A}\x{604B}' - . '\x{604C}\x{604D}\x{604E}\x{604F}\x{6050}\x{6051}\x{6052}\x{6053}\x{6054}' - . '\x{6055}\x{6057}\x{6058}\x{6059}\x{605A}\x{605B}\x{605C}\x{605D}\x{605E}' - . '\x{605F}\x{6062}\x{6063}\x{6064}\x{6065}\x{6066}\x{6067}\x{6068}\x{6069}' - . '\x{606A}\x{606B}\x{606C}\x{606D}\x{606E}\x{606F}\x{6070}\x{6072}\x{6073}' - . '\x{6075}\x{6076}\x{6077}\x{6078}\x{6079}\x{607A}\x{607B}\x{607C}\x{607D}' - . '\x{607E}\x{607F}\x{6080}\x{6081}\x{6082}\x{6083}\x{6084}\x{6085}\x{6086}' - . '\x{6087}\x{6088}\x{6089}\x{608A}\x{608B}\x{608C}\x{608D}\x{608E}\x{608F}' - . '\x{6090}\x{6092}\x{6094}\x{6095}\x{6096}\x{6097}\x{6098}\x{6099}\x{609A}' - . '\x{609B}\x{609C}\x{609D}\x{609E}\x{609F}\x{60A0}\x{60A1}\x{60A2}\x{60A3}' - . '\x{60A4}\x{60A6}\x{60A7}\x{60A8}\x{60AA}\x{60AB}\x{60AC}\x{60AD}\x{60AE}' - . '\x{60AF}\x{60B0}\x{60B1}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B7}' - . '\x{60B8}\x{60B9}\x{60BA}\x{60BB}\x{60BC}\x{60BD}\x{60BE}\x{60BF}\x{60C0}' - . '\x{60C1}\x{60C2}\x{60C3}\x{60C4}\x{60C5}\x{60C6}\x{60C7}\x{60C8}\x{60C9}' - . '\x{60CA}\x{60CB}\x{60CC}\x{60CD}\x{60CE}\x{60CF}\x{60D0}\x{60D1}\x{60D3}' - . '\x{60D4}\x{60D5}\x{60D7}\x{60D8}\x{60D9}\x{60DA}\x{60DB}\x{60DC}\x{60DD}' - . '\x{60DF}\x{60E0}\x{60E1}\x{60E2}\x{60E4}\x{60E6}\x{60E7}\x{60E8}\x{60E9}' - . '\x{60EA}\x{60EB}\x{60EC}\x{60ED}\x{60EE}\x{60EF}\x{60F0}\x{60F1}\x{60F2}' - . '\x{60F3}\x{60F4}\x{60F5}\x{60F6}\x{60F7}\x{60F8}\x{60F9}\x{60FA}\x{60FB}' - . '\x{60FC}\x{60FE}\x{60FF}\x{6100}\x{6101}\x{6103}\x{6104}\x{6105}\x{6106}' - . '\x{6108}\x{6109}\x{610A}\x{610B}\x{610C}\x{610D}\x{610E}\x{610F}\x{6110}' - . '\x{6112}\x{6113}\x{6114}\x{6115}\x{6116}\x{6117}\x{6118}\x{6119}\x{611A}' - . '\x{611B}\x{611C}\x{611D}\x{611F}\x{6120}\x{6122}\x{6123}\x{6124}\x{6125}' - . '\x{6126}\x{6127}\x{6128}\x{6129}\x{612A}\x{612B}\x{612C}\x{612D}\x{612E}' - . '\x{612F}\x{6130}\x{6132}\x{6134}\x{6136}\x{6137}\x{613A}\x{613B}\x{613C}' - . '\x{613D}\x{613E}\x{613F}\x{6140}\x{6141}\x{6142}\x{6143}\x{6144}\x{6145}' - . '\x{6146}\x{6147}\x{6148}\x{6149}\x{614A}\x{614B}\x{614C}\x{614D}\x{614E}' - . '\x{614F}\x{6150}\x{6151}\x{6152}\x{6153}\x{6154}\x{6155}\x{6156}\x{6157}' - . '\x{6158}\x{6159}\x{615A}\x{615B}\x{615C}\x{615D}\x{615E}\x{615F}\x{6161}' - . '\x{6162}\x{6163}\x{6164}\x{6165}\x{6166}\x{6167}\x{6168}\x{6169}\x{616A}' - . '\x{616B}\x{616C}\x{616D}\x{616E}\x{6170}\x{6171}\x{6172}\x{6173}\x{6174}' - . '\x{6175}\x{6176}\x{6177}\x{6178}\x{6179}\x{617A}\x{617C}\x{617E}\x{6180}' - . '\x{6181}\x{6182}\x{6183}\x{6184}\x{6185}\x{6187}\x{6188}\x{6189}\x{618A}' - . '\x{618B}\x{618C}\x{618D}\x{618E}\x{618F}\x{6190}\x{6191}\x{6192}\x{6193}' - . '\x{6194}\x{6195}\x{6196}\x{6198}\x{6199}\x{619A}\x{619B}\x{619D}\x{619E}' - . '\x{619F}\x{61A0}\x{61A1}\x{61A2}\x{61A3}\x{61A4}\x{61A5}\x{61A6}\x{61A7}' - . '\x{61A8}\x{61A9}\x{61AA}\x{61AB}\x{61AC}\x{61AD}\x{61AE}\x{61AF}\x{61B0}' - . '\x{61B1}\x{61B2}\x{61B3}\x{61B4}\x{61B5}\x{61B6}\x{61B7}\x{61B8}\x{61BA}' - . '\x{61BC}\x{61BD}\x{61BE}\x{61BF}\x{61C0}\x{61C1}\x{61C2}\x{61C3}\x{61C4}' - . '\x{61C5}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' - . '\x{61CE}\x{61CF}\x{61D0}\x{61D1}\x{61D2}\x{61D4}\x{61D6}\x{61D7}\x{61D8}' - . '\x{61D9}\x{61DA}\x{61DB}\x{61DC}\x{61DD}\x{61DE}\x{61DF}\x{61E0}\x{61E1}' - . '\x{61E2}\x{61E3}\x{61E4}\x{61E5}\x{61E6}\x{61E7}\x{61E8}\x{61E9}\x{61EA}' - . '\x{61EB}\x{61ED}\x{61EE}\x{61F0}\x{61F1}\x{61F2}\x{61F3}\x{61F5}\x{61F6}' - . '\x{61F7}\x{61F8}\x{61F9}\x{61FA}\x{61FB}\x{61FC}\x{61FD}\x{61FE}\x{61FF}' - . '\x{6200}\x{6201}\x{6202}\x{6203}\x{6204}\x{6206}\x{6207}\x{6208}\x{6209}' - . '\x{620A}\x{620B}\x{620C}\x{620D}\x{620E}\x{620F}\x{6210}\x{6211}\x{6212}' - . '\x{6213}\x{6214}\x{6215}\x{6216}\x{6217}\x{6218}\x{6219}\x{621A}\x{621B}' - . '\x{621C}\x{621D}\x{621E}\x{621F}\x{6220}\x{6221}\x{6222}\x{6223}\x{6224}' - . '\x{6225}\x{6226}\x{6227}\x{6228}\x{6229}\x{622A}\x{622B}\x{622C}\x{622D}' - . '\x{622E}\x{622F}\x{6230}\x{6231}\x{6232}\x{6233}\x{6234}\x{6236}\x{6237}' - . '\x{6238}\x{623A}\x{623B}\x{623C}\x{623D}\x{623E}\x{623F}\x{6240}\x{6241}' - . '\x{6242}\x{6243}\x{6244}\x{6245}\x{6246}\x{6247}\x{6248}\x{6249}\x{624A}' - . '\x{624B}\x{624C}\x{624D}\x{624E}\x{624F}\x{6250}\x{6251}\x{6252}\x{6253}' - . '\x{6254}\x{6255}\x{6256}\x{6258}\x{6259}\x{625A}\x{625B}\x{625C}\x{625D}' - . '\x{625E}\x{625F}\x{6260}\x{6261}\x{6262}\x{6263}\x{6264}\x{6265}\x{6266}' - . '\x{6267}\x{6268}\x{6269}\x{626A}\x{626B}\x{626C}\x{626D}\x{626E}\x{626F}' - . '\x{6270}\x{6271}\x{6272}\x{6273}\x{6274}\x{6275}\x{6276}\x{6277}\x{6278}' - . '\x{6279}\x{627A}\x{627B}\x{627C}\x{627D}\x{627E}\x{627F}\x{6280}\x{6281}' - . '\x{6283}\x{6284}\x{6285}\x{6286}\x{6287}\x{6288}\x{6289}\x{628A}\x{628B}' - . '\x{628C}\x{628E}\x{628F}\x{6290}\x{6291}\x{6292}\x{6293}\x{6294}\x{6295}' - . '\x{6296}\x{6297}\x{6298}\x{6299}\x{629A}\x{629B}\x{629C}\x{629E}\x{629F}' - . '\x{62A0}\x{62A1}\x{62A2}\x{62A3}\x{62A4}\x{62A5}\x{62A7}\x{62A8}\x{62A9}' - . '\x{62AA}\x{62AB}\x{62AC}\x{62AD}\x{62AE}\x{62AF}\x{62B0}\x{62B1}\x{62B2}' - . '\x{62B3}\x{62B4}\x{62B5}\x{62B6}\x{62B7}\x{62B8}\x{62B9}\x{62BA}\x{62BB}' - . '\x{62BC}\x{62BD}\x{62BE}\x{62BF}\x{62C0}\x{62C1}\x{62C2}\x{62C3}\x{62C4}' - . '\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CB}\x{62CC}\x{62CD}' - . '\x{62CE}\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D5}\x{62D6}' - . '\x{62D7}\x{62D8}\x{62D9}\x{62DA}\x{62DB}\x{62DC}\x{62DD}\x{62DF}\x{62E0}' - . '\x{62E1}\x{62E2}\x{62E3}\x{62E4}\x{62E5}\x{62E6}\x{62E7}\x{62E8}\x{62E9}' - . '\x{62EB}\x{62EC}\x{62ED}\x{62EE}\x{62EF}\x{62F0}\x{62F1}\x{62F2}\x{62F3}' - . '\x{62F4}\x{62F5}\x{62F6}\x{62F7}\x{62F8}\x{62F9}\x{62FA}\x{62FB}\x{62FC}' - . '\x{62FD}\x{62FE}\x{62FF}\x{6300}\x{6301}\x{6302}\x{6303}\x{6304}\x{6305}' - . '\x{6306}\x{6307}\x{6308}\x{6309}\x{630B}\x{630C}\x{630D}\x{630E}\x{630F}' - . '\x{6310}\x{6311}\x{6312}\x{6313}\x{6314}\x{6315}\x{6316}\x{6318}\x{6319}' - . '\x{631A}\x{631B}\x{631C}\x{631D}\x{631E}\x{631F}\x{6320}\x{6321}\x{6322}' - . '\x{6323}\x{6324}\x{6325}\x{6326}\x{6327}\x{6328}\x{6329}\x{632A}\x{632B}' - . '\x{632C}\x{632D}\x{632E}\x{632F}\x{6330}\x{6332}\x{6333}\x{6334}\x{6336}' - . '\x{6338}\x{6339}\x{633A}\x{633B}\x{633C}\x{633D}\x{633E}\x{6340}\x{6341}' - . '\x{6342}\x{6343}\x{6344}\x{6345}\x{6346}\x{6347}\x{6348}\x{6349}\x{634A}' - . '\x{634B}\x{634C}\x{634D}\x{634E}\x{634F}\x{6350}\x{6351}\x{6352}\x{6353}' - . '\x{6354}\x{6355}\x{6356}\x{6357}\x{6358}\x{6359}\x{635A}\x{635C}\x{635D}' - . '\x{635E}\x{635F}\x{6360}\x{6361}\x{6362}\x{6363}\x{6364}\x{6365}\x{6366}' - . '\x{6367}\x{6368}\x{6369}\x{636A}\x{636B}\x{636C}\x{636D}\x{636E}\x{636F}' - . '\x{6370}\x{6371}\x{6372}\x{6373}\x{6374}\x{6375}\x{6376}\x{6377}\x{6378}' - . '\x{6379}\x{637A}\x{637B}\x{637C}\x{637D}\x{637E}\x{6380}\x{6381}\x{6382}' - . '\x{6383}\x{6384}\x{6385}\x{6386}\x{6387}\x{6388}\x{6389}\x{638A}\x{638C}' - . '\x{638D}\x{638E}\x{638F}\x{6390}\x{6391}\x{6392}\x{6394}\x{6395}\x{6396}' - . '\x{6397}\x{6398}\x{6399}\x{639A}\x{639B}\x{639C}\x{639D}\x{639E}\x{639F}' - . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A4}\x{63A5}\x{63A6}\x{63A7}\x{63A8}' - . '\x{63A9}\x{63AA}\x{63AB}\x{63AC}\x{63AD}\x{63AE}\x{63AF}\x{63B0}\x{63B1}' - . '\x{63B2}\x{63B3}\x{63B4}\x{63B5}\x{63B6}\x{63B7}\x{63B8}\x{63B9}\x{63BA}' - . '\x{63BC}\x{63BD}\x{63BE}\x{63BF}\x{63C0}\x{63C1}\x{63C2}\x{63C3}\x{63C4}' - . '\x{63C5}\x{63C6}\x{63C7}\x{63C8}\x{63C9}\x{63CA}\x{63CB}\x{63CC}\x{63CD}' - . '\x{63CE}\x{63CF}\x{63D0}\x{63D2}\x{63D3}\x{63D4}\x{63D5}\x{63D6}\x{63D7}' - . '\x{63D8}\x{63D9}\x{63DA}\x{63DB}\x{63DC}\x{63DD}\x{63DE}\x{63DF}\x{63E0}' - . '\x{63E1}\x{63E2}\x{63E3}\x{63E4}\x{63E5}\x{63E6}\x{63E7}\x{63E8}\x{63E9}' - . '\x{63EA}\x{63EB}\x{63EC}\x{63ED}\x{63EE}\x{63EF}\x{63F0}\x{63F1}\x{63F2}' - . '\x{63F3}\x{63F4}\x{63F5}\x{63F6}\x{63F7}\x{63F8}\x{63F9}\x{63FA}\x{63FB}' - . '\x{63FC}\x{63FD}\x{63FE}\x{63FF}\x{6400}\x{6401}\x{6402}\x{6403}\x{6404}' - . '\x{6405}\x{6406}\x{6408}\x{6409}\x{640A}\x{640B}\x{640C}\x{640D}\x{640E}' - . '\x{640F}\x{6410}\x{6411}\x{6412}\x{6413}\x{6414}\x{6415}\x{6416}\x{6417}' - . '\x{6418}\x{6419}\x{641A}\x{641B}\x{641C}\x{641D}\x{641E}\x{641F}\x{6420}' - . '\x{6421}\x{6422}\x{6423}\x{6424}\x{6425}\x{6426}\x{6427}\x{6428}\x{6429}' - . '\x{642A}\x{642B}\x{642C}\x{642D}\x{642E}\x{642F}\x{6430}\x{6431}\x{6432}' - . '\x{6433}\x{6434}\x{6435}\x{6436}\x{6437}\x{6438}\x{6439}\x{643A}\x{643D}' - . '\x{643E}\x{643F}\x{6440}\x{6441}\x{6443}\x{6444}\x{6445}\x{6446}\x{6447}' - . '\x{6448}\x{644A}\x{644B}\x{644C}\x{644D}\x{644E}\x{644F}\x{6450}\x{6451}' - . '\x{6452}\x{6453}\x{6454}\x{6455}\x{6456}\x{6457}\x{6458}\x{6459}\x{645B}' - . '\x{645C}\x{645D}\x{645E}\x{645F}\x{6460}\x{6461}\x{6462}\x{6463}\x{6464}' - . '\x{6465}\x{6466}\x{6467}\x{6468}\x{6469}\x{646A}\x{646B}\x{646C}\x{646D}' - . '\x{646E}\x{646F}\x{6470}\x{6471}\x{6472}\x{6473}\x{6474}\x{6475}\x{6476}' - . '\x{6477}\x{6478}\x{6479}\x{647A}\x{647B}\x{647C}\x{647D}\x{647F}\x{6480}' - . '\x{6481}\x{6482}\x{6483}\x{6484}\x{6485}\x{6487}\x{6488}\x{6489}\x{648A}' - . '\x{648B}\x{648C}\x{648D}\x{648E}\x{648F}\x{6490}\x{6491}\x{6492}\x{6493}' - . '\x{6494}\x{6495}\x{6496}\x{6497}\x{6498}\x{6499}\x{649A}\x{649B}\x{649C}' - . '\x{649D}\x{649E}\x{649F}\x{64A0}\x{64A2}\x{64A3}\x{64A4}\x{64A5}\x{64A6}' - . '\x{64A7}\x{64A8}\x{64A9}\x{64AA}\x{64AB}\x{64AC}\x{64AD}\x{64AE}\x{64B0}' - . '\x{64B1}\x{64B2}\x{64B3}\x{64B4}\x{64B5}\x{64B7}\x{64B8}\x{64B9}\x{64BA}' - . '\x{64BB}\x{64BC}\x{64BD}\x{64BE}\x{64BF}\x{64C0}\x{64C1}\x{64C2}\x{64C3}' - . '\x{64C4}\x{64C5}\x{64C6}\x{64C7}\x{64C9}\x{64CA}\x{64CB}\x{64CC}\x{64CD}' - . '\x{64CE}\x{64CF}\x{64D0}\x{64D1}\x{64D2}\x{64D3}\x{64D4}\x{64D6}\x{64D7}' - . '\x{64D8}\x{64D9}\x{64DA}\x{64DB}\x{64DC}\x{64DD}\x{64DE}\x{64DF}\x{64E0}' - . '\x{64E2}\x{64E3}\x{64E4}\x{64E6}\x{64E7}\x{64E8}\x{64E9}\x{64EA}\x{64EB}' - . '\x{64EC}\x{64ED}\x{64EF}\x{64F0}\x{64F1}\x{64F2}\x{64F3}\x{64F4}\x{64F6}' - . '\x{64F7}\x{64F8}\x{64FA}\x{64FB}\x{64FC}\x{64FD}\x{64FE}\x{64FF}\x{6500}' - . '\x{6501}\x{6503}\x{6504}\x{6505}\x{6506}\x{6507}\x{6508}\x{6509}\x{650B}' - . '\x{650C}\x{650D}\x{650E}\x{650F}\x{6510}\x{6511}\x{6512}\x{6513}\x{6514}' - . '\x{6515}\x{6516}\x{6517}\x{6518}\x{6519}\x{651A}\x{651B}\x{651C}\x{651D}' - . '\x{651E}\x{6520}\x{6521}\x{6522}\x{6523}\x{6524}\x{6525}\x{6526}\x{6527}' - . '\x{6529}\x{652A}\x{652B}\x{652C}\x{652D}\x{652E}\x{652F}\x{6530}\x{6531}' - . '\x{6532}\x{6533}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}\x{653A}' - . '\x{653B}\x{653C}\x{653D}\x{653E}\x{653F}\x{6541}\x{6543}\x{6544}\x{6545}' - . '\x{6546}\x{6547}\x{6548}\x{6549}\x{654A}\x{654B}\x{654C}\x{654D}\x{654E}' - . '\x{654F}\x{6550}\x{6551}\x{6552}\x{6553}\x{6554}\x{6555}\x{6556}\x{6557}' - . '\x{6558}\x{6559}\x{655B}\x{655C}\x{655D}\x{655E}\x{6560}\x{6561}\x{6562}' - . '\x{6563}\x{6564}\x{6565}\x{6566}\x{6567}\x{6568}\x{6569}\x{656A}\x{656B}' - . '\x{656C}\x{656E}\x{656F}\x{6570}\x{6571}\x{6572}\x{6573}\x{6574}\x{6575}' - . '\x{6576}\x{6577}\x{6578}\x{6579}\x{657A}\x{657B}\x{657C}\x{657E}\x{657F}' - . '\x{6580}\x{6581}\x{6582}\x{6583}\x{6584}\x{6585}\x{6586}\x{6587}\x{6588}' - . '\x{6589}\x{658B}\x{658C}\x{658D}\x{658E}\x{658F}\x{6590}\x{6591}\x{6592}' - . '\x{6593}\x{6594}\x{6595}\x{6596}\x{6597}\x{6598}\x{6599}\x{659B}\x{659C}' - . '\x{659D}\x{659E}\x{659F}\x{65A0}\x{65A1}\x{65A2}\x{65A3}\x{65A4}\x{65A5}' - . '\x{65A6}\x{65A7}\x{65A8}\x{65A9}\x{65AA}\x{65AB}\x{65AC}\x{65AD}\x{65AE}' - . '\x{65AF}\x{65B0}\x{65B1}\x{65B2}\x{65B3}\x{65B4}\x{65B6}\x{65B7}\x{65B8}' - . '\x{65B9}\x{65BA}\x{65BB}\x{65BC}\x{65BD}\x{65BF}\x{65C0}\x{65C1}\x{65C2}' - . '\x{65C3}\x{65C4}\x{65C5}\x{65C6}\x{65C7}\x{65CA}\x{65CB}\x{65CC}\x{65CD}' - . '\x{65CE}\x{65CF}\x{65D0}\x{65D2}\x{65D3}\x{65D4}\x{65D5}\x{65D6}\x{65D7}' - . '\x{65DA}\x{65DB}\x{65DD}\x{65DE}\x{65DF}\x{65E0}\x{65E1}\x{65E2}\x{65E3}' - . '\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}\x{65EB}\x{65EC}\x{65ED}\x{65EE}' - . '\x{65EF}\x{65F0}\x{65F1}\x{65F2}\x{65F3}\x{65F4}\x{65F5}\x{65F6}\x{65F7}' - . '\x{65F8}\x{65FA}\x{65FB}\x{65FC}\x{65FD}\x{6600}\x{6601}\x{6602}\x{6603}' - . '\x{6604}\x{6605}\x{6606}\x{6607}\x{6608}\x{6609}\x{660A}\x{660B}\x{660C}' - . '\x{660D}\x{660E}\x{660F}\x{6610}\x{6611}\x{6612}\x{6613}\x{6614}\x{6615}' - . '\x{6616}\x{6618}\x{6619}\x{661A}\x{661B}\x{661C}\x{661D}\x{661F}\x{6620}' - . '\x{6621}\x{6622}\x{6623}\x{6624}\x{6625}\x{6626}\x{6627}\x{6628}\x{6629}' - . '\x{662A}\x{662B}\x{662D}\x{662E}\x{662F}\x{6630}\x{6631}\x{6632}\x{6633}' - . '\x{6634}\x{6635}\x{6636}\x{6639}\x{663A}\x{663C}\x{663D}\x{663E}\x{6640}' - . '\x{6641}\x{6642}\x{6643}\x{6644}\x{6645}\x{6646}\x{6647}\x{6649}\x{664A}' - . '\x{664B}\x{664C}\x{664E}\x{664F}\x{6650}\x{6651}\x{6652}\x{6653}\x{6654}' - . '\x{6655}\x{6656}\x{6657}\x{6658}\x{6659}\x{665A}\x{665B}\x{665C}\x{665D}' - . '\x{665E}\x{665F}\x{6661}\x{6662}\x{6664}\x{6665}\x{6666}\x{6668}\x{6669}' - . '\x{666A}\x{666B}\x{666C}\x{666D}\x{666E}\x{666F}\x{6670}\x{6671}\x{6672}' - . '\x{6673}\x{6674}\x{6675}\x{6676}\x{6677}\x{6678}\x{6679}\x{667A}\x{667B}' - . '\x{667C}\x{667D}\x{667E}\x{667F}\x{6680}\x{6681}\x{6682}\x{6683}\x{6684}' - . '\x{6685}\x{6686}\x{6687}\x{6688}\x{6689}\x{668A}\x{668B}\x{668C}\x{668D}' - . '\x{668E}\x{668F}\x{6690}\x{6691}\x{6693}\x{6694}\x{6695}\x{6696}\x{6697}' - . '\x{6698}\x{6699}\x{669A}\x{669B}\x{669D}\x{669F}\x{66A0}\x{66A1}\x{66A2}' - . '\x{66A3}\x{66A4}\x{66A5}\x{66A6}\x{66A7}\x{66A8}\x{66A9}\x{66AA}\x{66AB}' - . '\x{66AE}\x{66AF}\x{66B0}\x{66B1}\x{66B2}\x{66B3}\x{66B4}\x{66B5}\x{66B6}' - . '\x{66B7}\x{66B8}\x{66B9}\x{66BA}\x{66BB}\x{66BC}\x{66BD}\x{66BE}\x{66BF}' - . '\x{66C0}\x{66C1}\x{66C2}\x{66C3}\x{66C4}\x{66C5}\x{66C6}\x{66C7}\x{66C8}' - . '\x{66C9}\x{66CA}\x{66CB}\x{66CC}\x{66CD}\x{66CE}\x{66CF}\x{66D1}\x{66D2}' - . '\x{66D4}\x{66D5}\x{66D6}\x{66D8}\x{66D9}\x{66DA}\x{66DB}\x{66DC}\x{66DD}' - . '\x{66DE}\x{66E0}\x{66E1}\x{66E2}\x{66E3}\x{66E4}\x{66E5}\x{66E6}\x{66E7}' - . '\x{66E8}\x{66E9}\x{66EA}\x{66EB}\x{66EC}\x{66ED}\x{66EE}\x{66F0}\x{66F1}' - . '\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F6}\x{66F7}\x{66F8}\x{66F9}\x{66FA}' - . '\x{66FB}\x{66FC}\x{66FE}\x{66FF}\x{6700}\x{6701}\x{6703}\x{6704}\x{6705}' - . '\x{6706}\x{6708}\x{6709}\x{670A}\x{670B}\x{670C}\x{670D}\x{670E}\x{670F}' - . '\x{6710}\x{6711}\x{6712}\x{6713}\x{6714}\x{6715}\x{6716}\x{6717}\x{6718}' - . '\x{671A}\x{671B}\x{671C}\x{671D}\x{671E}\x{671F}\x{6720}\x{6721}\x{6722}' - . '\x{6723}\x{6725}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}\x{672D}' - . '\x{672E}\x{672F}\x{6730}\x{6731}\x{6732}\x{6733}\x{6734}\x{6735}\x{6736}' - . '\x{6737}\x{6738}\x{6739}\x{673A}\x{673B}\x{673C}\x{673D}\x{673E}\x{673F}' - . '\x{6740}\x{6741}\x{6742}\x{6743}\x{6744}\x{6745}\x{6746}\x{6747}\x{6748}' - . '\x{6749}\x{674A}\x{674B}\x{674C}\x{674D}\x{674E}\x{674F}\x{6750}\x{6751}' - . '\x{6752}\x{6753}\x{6754}\x{6755}\x{6756}\x{6757}\x{6758}\x{6759}\x{675A}' - . '\x{675B}\x{675C}\x{675D}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' - . '\x{6764}\x{6765}\x{6766}\x{6768}\x{6769}\x{676A}\x{676B}\x{676C}\x{676D}' - . '\x{676E}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}\x{6774}\x{6775}\x{6776}' - . '\x{6777}\x{6778}\x{6779}\x{677A}\x{677B}\x{677C}\x{677D}\x{677E}\x{677F}' - . '\x{6780}\x{6781}\x{6782}\x{6783}\x{6784}\x{6785}\x{6786}\x{6787}\x{6789}' - . '\x{678A}\x{678B}\x{678C}\x{678D}\x{678E}\x{678F}\x{6790}\x{6791}\x{6792}' - . '\x{6793}\x{6794}\x{6795}\x{6797}\x{6798}\x{6799}\x{679A}\x{679B}\x{679C}' - . '\x{679D}\x{679E}\x{679F}\x{67A0}\x{67A1}\x{67A2}\x{67A3}\x{67A4}\x{67A5}' - . '\x{67A6}\x{67A7}\x{67A8}\x{67AA}\x{67AB}\x{67AC}\x{67AD}\x{67AE}\x{67AF}' - . '\x{67B0}\x{67B1}\x{67B2}\x{67B3}\x{67B4}\x{67B5}\x{67B6}\x{67B7}\x{67B8}' - . '\x{67B9}\x{67BA}\x{67BB}\x{67BC}\x{67BE}\x{67C0}\x{67C1}\x{67C2}\x{67C3}' - . '\x{67C4}\x{67C5}\x{67C6}\x{67C7}\x{67C8}\x{67C9}\x{67CA}\x{67CB}\x{67CC}' - . '\x{67CD}\x{67CE}\x{67CF}\x{67D0}\x{67D1}\x{67D2}\x{67D3}\x{67D4}\x{67D6}' - . '\x{67D8}\x{67D9}\x{67DA}\x{67DB}\x{67DC}\x{67DD}\x{67DE}\x{67DF}\x{67E0}' - . '\x{67E1}\x{67E2}\x{67E3}\x{67E4}\x{67E5}\x{67E6}\x{67E7}\x{67E8}\x{67E9}' - . '\x{67EA}\x{67EB}\x{67EC}\x{67ED}\x{67EE}\x{67EF}\x{67F0}\x{67F1}\x{67F2}' - . '\x{67F3}\x{67F4}\x{67F5}\x{67F6}\x{67F7}\x{67F8}\x{67FA}\x{67FB}\x{67FC}' - . '\x{67FD}\x{67FE}\x{67FF}\x{6800}\x{6802}\x{6803}\x{6804}\x{6805}\x{6806}' - . '\x{6807}\x{6808}\x{6809}\x{680A}\x{680B}\x{680C}\x{680D}\x{680E}\x{680F}' - . '\x{6810}\x{6811}\x{6812}\x{6813}\x{6814}\x{6816}\x{6817}\x{6818}\x{6819}' - . '\x{681A}\x{681B}\x{681C}\x{681D}\x{681F}\x{6820}\x{6821}\x{6822}\x{6823}' - . '\x{6824}\x{6825}\x{6826}\x{6828}\x{6829}\x{682A}\x{682B}\x{682C}\x{682D}' - . '\x{682E}\x{682F}\x{6831}\x{6832}\x{6833}\x{6834}\x{6835}\x{6836}\x{6837}' - . '\x{6838}\x{6839}\x{683A}\x{683B}\x{683C}\x{683D}\x{683E}\x{683F}\x{6840}' - . '\x{6841}\x{6842}\x{6843}\x{6844}\x{6845}\x{6846}\x{6847}\x{6848}\x{6849}' - . '\x{684A}\x{684B}\x{684C}\x{684D}\x{684E}\x{684F}\x{6850}\x{6851}\x{6852}' - . '\x{6853}\x{6854}\x{6855}\x{6856}\x{6857}\x{685B}\x{685D}\x{6860}\x{6861}' - . '\x{6862}\x{6863}\x{6864}\x{6865}\x{6866}\x{6867}\x{6868}\x{6869}\x{686A}' - . '\x{686B}\x{686C}\x{686D}\x{686E}\x{686F}\x{6870}\x{6871}\x{6872}\x{6873}' - . '\x{6874}\x{6875}\x{6876}\x{6877}\x{6878}\x{6879}\x{687B}\x{687C}\x{687D}' - . '\x{687E}\x{687F}\x{6880}\x{6881}\x{6882}\x{6883}\x{6884}\x{6885}\x{6886}' - . '\x{6887}\x{6888}\x{6889}\x{688A}\x{688B}\x{688C}\x{688D}\x{688E}\x{688F}' - . '\x{6890}\x{6891}\x{6892}\x{6893}\x{6894}\x{6896}\x{6897}\x{6898}\x{689A}' - . '\x{689B}\x{689C}\x{689D}\x{689E}\x{689F}\x{68A0}\x{68A1}\x{68A2}\x{68A3}' - . '\x{68A4}\x{68A6}\x{68A7}\x{68A8}\x{68A9}\x{68AA}\x{68AB}\x{68AC}\x{68AD}' - . '\x{68AE}\x{68AF}\x{68B0}\x{68B1}\x{68B2}\x{68B3}\x{68B4}\x{68B5}\x{68B6}' - . '\x{68B7}\x{68B9}\x{68BB}\x{68BC}\x{68BD}\x{68BE}\x{68BF}\x{68C0}\x{68C1}' - . '\x{68C2}\x{68C4}\x{68C6}\x{68C7}\x{68C8}\x{68C9}\x{68CA}\x{68CB}\x{68CC}' - . '\x{68CD}\x{68CE}\x{68CF}\x{68D0}\x{68D1}\x{68D2}\x{68D3}\x{68D4}\x{68D5}' - . '\x{68D6}\x{68D7}\x{68D8}\x{68DA}\x{68DB}\x{68DC}\x{68DD}\x{68DE}\x{68DF}' - . '\x{68E0}\x{68E1}\x{68E3}\x{68E4}\x{68E6}\x{68E7}\x{68E8}\x{68E9}\x{68EA}' - . '\x{68EB}\x{68EC}\x{68ED}\x{68EE}\x{68EF}\x{68F0}\x{68F1}\x{68F2}\x{68F3}' - . '\x{68F4}\x{68F5}\x{68F6}\x{68F7}\x{68F8}\x{68F9}\x{68FA}\x{68FB}\x{68FC}' - . '\x{68FD}\x{68FE}\x{68FF}\x{6901}\x{6902}\x{6903}\x{6904}\x{6905}\x{6906}' - . '\x{6907}\x{6908}\x{690A}\x{690B}\x{690C}\x{690D}\x{690E}\x{690F}\x{6910}' - . '\x{6911}\x{6912}\x{6913}\x{6914}\x{6915}\x{6916}\x{6917}\x{6918}\x{6919}' - . '\x{691A}\x{691B}\x{691C}\x{691D}\x{691E}\x{691F}\x{6920}\x{6921}\x{6922}' - . '\x{6923}\x{6924}\x{6925}\x{6926}\x{6927}\x{6928}\x{6929}\x{692A}\x{692B}' - . '\x{692C}\x{692D}\x{692E}\x{692F}\x{6930}\x{6931}\x{6932}\x{6933}\x{6934}' - . '\x{6935}\x{6936}\x{6937}\x{6938}\x{6939}\x{693A}\x{693B}\x{693C}\x{693D}' - . '\x{693F}\x{6940}\x{6941}\x{6942}\x{6943}\x{6944}\x{6945}\x{6946}\x{6947}' - . '\x{6948}\x{6949}\x{694A}\x{694B}\x{694C}\x{694E}\x{694F}\x{6950}\x{6951}' - . '\x{6952}\x{6953}\x{6954}\x{6955}\x{6956}\x{6957}\x{6958}\x{6959}\x{695A}' - . '\x{695B}\x{695C}\x{695D}\x{695E}\x{695F}\x{6960}\x{6961}\x{6962}\x{6963}' - . '\x{6964}\x{6965}\x{6966}\x{6967}\x{6968}\x{6969}\x{696A}\x{696B}\x{696C}' - . '\x{696D}\x{696E}\x{696F}\x{6970}\x{6971}\x{6972}\x{6973}\x{6974}\x{6975}' - . '\x{6976}\x{6977}\x{6978}\x{6979}\x{697A}\x{697B}\x{697C}\x{697D}\x{697E}' - . '\x{697F}\x{6980}\x{6981}\x{6982}\x{6983}\x{6984}\x{6985}\x{6986}\x{6987}' - . '\x{6988}\x{6989}\x{698A}\x{698B}\x{698C}\x{698D}\x{698E}\x{698F}\x{6990}' - . '\x{6991}\x{6992}\x{6993}\x{6994}\x{6995}\x{6996}\x{6997}\x{6998}\x{6999}' - . '\x{699A}\x{699B}\x{699C}\x{699D}\x{699E}\x{69A0}\x{69A1}\x{69A3}\x{69A4}' - . '\x{69A5}\x{69A6}\x{69A7}\x{69A8}\x{69A9}\x{69AA}\x{69AB}\x{69AC}\x{69AD}' - . '\x{69AE}\x{69AF}\x{69B0}\x{69B1}\x{69B2}\x{69B3}\x{69B4}\x{69B5}\x{69B6}' - . '\x{69B7}\x{69B8}\x{69B9}\x{69BA}\x{69BB}\x{69BC}\x{69BD}\x{69BE}\x{69BF}' - . '\x{69C1}\x{69C2}\x{69C3}\x{69C4}\x{69C5}\x{69C6}\x{69C7}\x{69C8}\x{69C9}' - . '\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}\x{69CF}\x{69D0}\x{69D3}\x{69D4}' - . '\x{69D8}\x{69D9}\x{69DA}\x{69DB}\x{69DC}\x{69DD}\x{69DE}\x{69DF}\x{69E0}' - . '\x{69E1}\x{69E2}\x{69E3}\x{69E4}\x{69E5}\x{69E6}\x{69E7}\x{69E8}\x{69E9}' - . '\x{69EA}\x{69EB}\x{69EC}\x{69ED}\x{69EE}\x{69EF}\x{69F0}\x{69F1}\x{69F2}' - . '\x{69F3}\x{69F4}\x{69F5}\x{69F6}\x{69F7}\x{69F8}\x{69FA}\x{69FB}\x{69FC}' - . '\x{69FD}\x{69FE}\x{69FF}\x{6A00}\x{6A01}\x{6A02}\x{6A04}\x{6A05}\x{6A06}' - . '\x{6A07}\x{6A08}\x{6A09}\x{6A0A}\x{6A0B}\x{6A0D}\x{6A0E}\x{6A0F}\x{6A10}' - . '\x{6A11}\x{6A12}\x{6A13}\x{6A14}\x{6A15}\x{6A16}\x{6A17}\x{6A18}\x{6A19}' - . '\x{6A1A}\x{6A1B}\x{6A1D}\x{6A1E}\x{6A1F}\x{6A20}\x{6A21}\x{6A22}\x{6A23}' - . '\x{6A25}\x{6A26}\x{6A27}\x{6A28}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2C}\x{6A2D}' - . '\x{6A2E}\x{6A2F}\x{6A30}\x{6A31}\x{6A32}\x{6A33}\x{6A34}\x{6A35}\x{6A36}' - . '\x{6A38}\x{6A39}\x{6A3A}\x{6A3B}\x{6A3C}\x{6A3D}\x{6A3E}\x{6A3F}\x{6A40}' - . '\x{6A41}\x{6A42}\x{6A43}\x{6A44}\x{6A45}\x{6A46}\x{6A47}\x{6A48}\x{6A49}' - . '\x{6A4B}\x{6A4C}\x{6A4D}\x{6A4E}\x{6A4F}\x{6A50}\x{6A51}\x{6A52}\x{6A54}' - . '\x{6A55}\x{6A56}\x{6A57}\x{6A58}\x{6A59}\x{6A5A}\x{6A5B}\x{6A5D}\x{6A5E}' - . '\x{6A5F}\x{6A60}\x{6A61}\x{6A62}\x{6A63}\x{6A64}\x{6A65}\x{6A66}\x{6A67}' - . '\x{6A68}\x{6A69}\x{6A6A}\x{6A6B}\x{6A6C}\x{6A6D}\x{6A6F}\x{6A71}\x{6A72}' - . '\x{6A73}\x{6A74}\x{6A75}\x{6A76}\x{6A77}\x{6A78}\x{6A79}\x{6A7A}\x{6A7B}' - . '\x{6A7C}\x{6A7D}\x{6A7E}\x{6A7F}\x{6A80}\x{6A81}\x{6A82}\x{6A83}\x{6A84}' - . '\x{6A85}\x{6A87}\x{6A88}\x{6A89}\x{6A8B}\x{6A8C}\x{6A8D}\x{6A8E}\x{6A90}' - . '\x{6A91}\x{6A92}\x{6A93}\x{6A94}\x{6A95}\x{6A96}\x{6A97}\x{6A98}\x{6A9A}' - . '\x{6A9B}\x{6A9C}\x{6A9E}\x{6A9F}\x{6AA0}\x{6AA1}\x{6AA2}\x{6AA3}\x{6AA4}' - . '\x{6AA5}\x{6AA6}\x{6AA7}\x{6AA8}\x{6AA9}\x{6AAB}\x{6AAC}\x{6AAD}\x{6AAE}' - . '\x{6AAF}\x{6AB0}\x{6AB2}\x{6AB3}\x{6AB4}\x{6AB5}\x{6AB6}\x{6AB7}\x{6AB8}' - . '\x{6AB9}\x{6ABA}\x{6ABB}\x{6ABC}\x{6ABD}\x{6ABF}\x{6AC1}\x{6AC2}\x{6AC3}' - . '\x{6AC5}\x{6AC6}\x{6AC7}\x{6ACA}\x{6ACB}\x{6ACC}\x{6ACD}\x{6ACE}\x{6ACF}' - . '\x{6AD0}\x{6AD1}\x{6AD2}\x{6AD3}\x{6AD4}\x{6AD5}\x{6AD6}\x{6AD7}\x{6AD9}' - . '\x{6ADA}\x{6ADB}\x{6ADC}\x{6ADD}\x{6ADE}\x{6ADF}\x{6AE0}\x{6AE1}\x{6AE2}' - . '\x{6AE3}\x{6AE4}\x{6AE5}\x{6AE6}\x{6AE7}\x{6AE8}\x{6AEA}\x{6AEB}\x{6AEC}' - . '\x{6AED}\x{6AEE}\x{6AEF}\x{6AF0}\x{6AF1}\x{6AF2}\x{6AF3}\x{6AF4}\x{6AF5}' - . '\x{6AF6}\x{6AF7}\x{6AF8}\x{6AF9}\x{6AFA}\x{6AFB}\x{6AFC}\x{6AFD}\x{6AFE}' - . '\x{6AFF}\x{6B00}\x{6B01}\x{6B02}\x{6B03}\x{6B04}\x{6B05}\x{6B06}\x{6B07}' - . '\x{6B08}\x{6B09}\x{6B0A}\x{6B0B}\x{6B0C}\x{6B0D}\x{6B0F}\x{6B10}\x{6B11}' - . '\x{6B12}\x{6B13}\x{6B14}\x{6B15}\x{6B16}\x{6B17}\x{6B18}\x{6B19}\x{6B1A}' - . '\x{6B1C}\x{6B1D}\x{6B1E}\x{6B1F}\x{6B20}\x{6B21}\x{6B22}\x{6B23}\x{6B24}' - . '\x{6B25}\x{6B26}\x{6B27}\x{6B28}\x{6B29}\x{6B2A}\x{6B2B}\x{6B2C}\x{6B2D}' - . '\x{6B2F}\x{6B30}\x{6B31}\x{6B32}\x{6B33}\x{6B34}\x{6B36}\x{6B37}\x{6B38}' - . '\x{6B39}\x{6B3A}\x{6B3B}\x{6B3C}\x{6B3D}\x{6B3E}\x{6B3F}\x{6B41}\x{6B42}' - . '\x{6B43}\x{6B44}\x{6B45}\x{6B46}\x{6B47}\x{6B48}\x{6B49}\x{6B4A}\x{6B4B}' - . '\x{6B4C}\x{6B4D}\x{6B4E}\x{6B4F}\x{6B50}\x{6B51}\x{6B52}\x{6B53}\x{6B54}' - . '\x{6B55}\x{6B56}\x{6B59}\x{6B5A}\x{6B5B}\x{6B5C}\x{6B5E}\x{6B5F}\x{6B60}' - . '\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B65}\x{6B66}\x{6B67}\x{6B69}\x{6B6A}' - . '\x{6B6B}\x{6B6D}\x{6B6F}\x{6B70}\x{6B72}\x{6B73}\x{6B74}\x{6B76}\x{6B77}' - . '\x{6B78}\x{6B79}\x{6B7A}\x{6B7B}\x{6B7C}\x{6B7E}\x{6B7F}\x{6B80}\x{6B81}' - . '\x{6B82}\x{6B83}\x{6B84}\x{6B85}\x{6B86}\x{6B87}\x{6B88}\x{6B89}\x{6B8A}' - . '\x{6B8B}\x{6B8C}\x{6B8D}\x{6B8E}\x{6B8F}\x{6B90}\x{6B91}\x{6B92}\x{6B93}' - . '\x{6B94}\x{6B95}\x{6B96}\x{6B97}\x{6B98}\x{6B99}\x{6B9A}\x{6B9B}\x{6B9C}' - . '\x{6B9D}\x{6B9E}\x{6B9F}\x{6BA0}\x{6BA1}\x{6BA2}\x{6BA3}\x{6BA4}\x{6BA5}' - . '\x{6BA6}\x{6BA7}\x{6BA8}\x{6BA9}\x{6BAA}\x{6BAB}\x{6BAC}\x{6BAD}\x{6BAE}' - . '\x{6BAF}\x{6BB0}\x{6BB2}\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB6}\x{6BB7}\x{6BB9}' - . '\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBD}\x{6BBE}\x{6BBF}\x{6BC0}\x{6BC1}\x{6BC2}' - . '\x{6BC3}\x{6BC4}\x{6BC5}\x{6BC6}\x{6BC7}\x{6BC8}\x{6BC9}\x{6BCA}\x{6BCB}' - . '\x{6BCC}\x{6BCD}\x{6BCE}\x{6BCF}\x{6BD0}\x{6BD1}\x{6BD2}\x{6BD3}\x{6BD4}' - . '\x{6BD5}\x{6BD6}\x{6BD7}\x{6BD8}\x{6BD9}\x{6BDA}\x{6BDB}\x{6BDC}\x{6BDD}' - . '\x{6BDE}\x{6BDF}\x{6BE0}\x{6BE1}\x{6BE2}\x{6BE3}\x{6BE4}\x{6BE5}\x{6BE6}' - . '\x{6BE7}\x{6BE8}\x{6BEA}\x{6BEB}\x{6BEC}\x{6BED}\x{6BEE}\x{6BEF}\x{6BF0}' - . '\x{6BF2}\x{6BF3}\x{6BF5}\x{6BF6}\x{6BF7}\x{6BF8}\x{6BF9}\x{6BFB}\x{6BFC}' - . '\x{6BFD}\x{6BFE}\x{6BFF}\x{6C00}\x{6C01}\x{6C02}\x{6C03}\x{6C04}\x{6C05}' - . '\x{6C06}\x{6C07}\x{6C08}\x{6C09}\x{6C0B}\x{6C0C}\x{6C0D}\x{6C0E}\x{6C0F}' - . '\x{6C10}\x{6C11}\x{6C12}\x{6C13}\x{6C14}\x{6C15}\x{6C16}\x{6C18}\x{6C19}' - . '\x{6C1A}\x{6C1B}\x{6C1D}\x{6C1E}\x{6C1F}\x{6C20}\x{6C21}\x{6C22}\x{6C23}' - . '\x{6C24}\x{6C25}\x{6C26}\x{6C27}\x{6C28}\x{6C29}\x{6C2A}\x{6C2B}\x{6C2C}' - . '\x{6C2E}\x{6C2F}\x{6C30}\x{6C31}\x{6C32}\x{6C33}\x{6C34}\x{6C35}\x{6C36}' - . '\x{6C37}\x{6C38}\x{6C3A}\x{6C3B}\x{6C3D}\x{6C3E}\x{6C3F}\x{6C40}\x{6C41}' - . '\x{6C42}\x{6C43}\x{6C44}\x{6C46}\x{6C47}\x{6C48}\x{6C49}\x{6C4A}\x{6C4B}' - . '\x{6C4C}\x{6C4D}\x{6C4E}\x{6C4F}\x{6C50}\x{6C51}\x{6C52}\x{6C53}\x{6C54}' - . '\x{6C55}\x{6C56}\x{6C57}\x{6C58}\x{6C59}\x{6C5A}\x{6C5B}\x{6C5C}\x{6C5D}' - . '\x{6C5E}\x{6C5F}\x{6C60}\x{6C61}\x{6C62}\x{6C63}\x{6C64}\x{6C65}\x{6C66}' - . '\x{6C67}\x{6C68}\x{6C69}\x{6C6A}\x{6C6B}\x{6C6D}\x{6C6F}\x{6C70}\x{6C71}' - . '\x{6C72}\x{6C73}\x{6C74}\x{6C75}\x{6C76}\x{6C77}\x{6C78}\x{6C79}\x{6C7A}' - . '\x{6C7B}\x{6C7C}\x{6C7D}\x{6C7E}\x{6C7F}\x{6C80}\x{6C81}\x{6C82}\x{6C83}' - . '\x{6C84}\x{6C85}\x{6C86}\x{6C87}\x{6C88}\x{6C89}\x{6C8A}\x{6C8B}\x{6C8C}' - . '\x{6C8D}\x{6C8E}\x{6C8F}\x{6C90}\x{6C91}\x{6C92}\x{6C93}\x{6C94}\x{6C95}' - . '\x{6C96}\x{6C97}\x{6C98}\x{6C99}\x{6C9A}\x{6C9B}\x{6C9C}\x{6C9D}\x{6C9E}' - . '\x{6C9F}\x{6CA1}\x{6CA2}\x{6CA3}\x{6CA4}\x{6CA5}\x{6CA6}\x{6CA7}\x{6CA8}' - . '\x{6CA9}\x{6CAA}\x{6CAB}\x{6CAC}\x{6CAD}\x{6CAE}\x{6CAF}\x{6CB0}\x{6CB1}' - . '\x{6CB2}\x{6CB3}\x{6CB4}\x{6CB5}\x{6CB6}\x{6CB7}\x{6CB8}\x{6CB9}\x{6CBA}' - . '\x{6CBB}\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC0}\x{6CC1}\x{6CC2}\x{6CC3}' - . '\x{6CC4}\x{6CC5}\x{6CC6}\x{6CC7}\x{6CC8}\x{6CC9}\x{6CCA}\x{6CCB}\x{6CCC}' - . '\x{6CCD}\x{6CCE}\x{6CCF}\x{6CD0}\x{6CD1}\x{6CD2}\x{6CD3}\x{6CD4}\x{6CD5}' - . '\x{6CD6}\x{6CD7}\x{6CD9}\x{6CDA}\x{6CDB}\x{6CDC}\x{6CDD}\x{6CDE}\x{6CDF}' - . '\x{6CE0}\x{6CE1}\x{6CE2}\x{6CE3}\x{6CE4}\x{6CE5}\x{6CE6}\x{6CE7}\x{6CE8}' - . '\x{6CE9}\x{6CEA}\x{6CEB}\x{6CEC}\x{6CED}\x{6CEE}\x{6CEF}\x{6CF0}\x{6CF1}' - . '\x{6CF2}\x{6CF3}\x{6CF5}\x{6CF6}\x{6CF7}\x{6CF8}\x{6CF9}\x{6CFA}\x{6CFB}' - . '\x{6CFC}\x{6CFD}\x{6CFE}\x{6CFF}\x{6D00}\x{6D01}\x{6D03}\x{6D04}\x{6D05}' - . '\x{6D06}\x{6D07}\x{6D08}\x{6D09}\x{6D0A}\x{6D0B}\x{6D0C}\x{6D0D}\x{6D0E}' - . '\x{6D0F}\x{6D10}\x{6D11}\x{6D12}\x{6D13}\x{6D14}\x{6D15}\x{6D16}\x{6D17}' - . '\x{6D18}\x{6D19}\x{6D1A}\x{6D1B}\x{6D1D}\x{6D1E}\x{6D1F}\x{6D20}\x{6D21}' - . '\x{6D22}\x{6D23}\x{6D25}\x{6D26}\x{6D27}\x{6D28}\x{6D29}\x{6D2A}\x{6D2B}' - . '\x{6D2C}\x{6D2D}\x{6D2E}\x{6D2F}\x{6D30}\x{6D31}\x{6D32}\x{6D33}\x{6D34}' - . '\x{6D35}\x{6D36}\x{6D37}\x{6D38}\x{6D39}\x{6D3A}\x{6D3B}\x{6D3C}\x{6D3D}' - . '\x{6D3E}\x{6D3F}\x{6D40}\x{6D41}\x{6D42}\x{6D43}\x{6D44}\x{6D45}\x{6D46}' - . '\x{6D47}\x{6D48}\x{6D49}\x{6D4A}\x{6D4B}\x{6D4C}\x{6D4D}\x{6D4E}\x{6D4F}' - . '\x{6D50}\x{6D51}\x{6D52}\x{6D53}\x{6D54}\x{6D55}\x{6D56}\x{6D57}\x{6D58}' - . '\x{6D59}\x{6D5A}\x{6D5B}\x{6D5C}\x{6D5D}\x{6D5E}\x{6D5F}\x{6D60}\x{6D61}' - . '\x{6D62}\x{6D63}\x{6D64}\x{6D65}\x{6D66}\x{6D67}\x{6D68}\x{6D69}\x{6D6A}' - . '\x{6D6B}\x{6D6C}\x{6D6D}\x{6D6E}\x{6D6F}\x{6D70}\x{6D72}\x{6D73}\x{6D74}' - . '\x{6D75}\x{6D76}\x{6D77}\x{6D78}\x{6D79}\x{6D7A}\x{6D7B}\x{6D7C}\x{6D7D}' - . '\x{6D7E}\x{6D7F}\x{6D80}\x{6D82}\x{6D83}\x{6D84}\x{6D85}\x{6D86}\x{6D87}' - . '\x{6D88}\x{6D89}\x{6D8A}\x{6D8B}\x{6D8C}\x{6D8D}\x{6D8E}\x{6D8F}\x{6D90}' - . '\x{6D91}\x{6D92}\x{6D93}\x{6D94}\x{6D95}\x{6D97}\x{6D98}\x{6D99}\x{6D9A}' - . '\x{6D9B}\x{6D9D}\x{6D9E}\x{6D9F}\x{6DA0}\x{6DA1}\x{6DA2}\x{6DA3}\x{6DA4}' - . '\x{6DA5}\x{6DA6}\x{6DA7}\x{6DA8}\x{6DA9}\x{6DAA}\x{6DAB}\x{6DAC}\x{6DAD}' - . '\x{6DAE}\x{6DAF}\x{6DB2}\x{6DB3}\x{6DB4}\x{6DB5}\x{6DB7}\x{6DB8}\x{6DB9}' - . '\x{6DBA}\x{6DBB}\x{6DBC}\x{6DBD}\x{6DBE}\x{6DBF}\x{6DC0}\x{6DC1}\x{6DC2}' - . '\x{6DC3}\x{6DC4}\x{6DC5}\x{6DC6}\x{6DC7}\x{6DC8}\x{6DC9}\x{6DCA}\x{6DCB}' - . '\x{6DCC}\x{6DCD}\x{6DCE}\x{6DCF}\x{6DD0}\x{6DD1}\x{6DD2}\x{6DD3}\x{6DD4}' - . '\x{6DD5}\x{6DD6}\x{6DD7}\x{6DD8}\x{6DD9}\x{6DDA}\x{6DDB}\x{6DDC}\x{6DDD}' - . '\x{6DDE}\x{6DDF}\x{6DE0}\x{6DE1}\x{6DE2}\x{6DE3}\x{6DE4}\x{6DE5}\x{6DE6}' - . '\x{6DE7}\x{6DE8}\x{6DE9}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DED}\x{6DEE}\x{6DEF}' - . '\x{6DF0}\x{6DF1}\x{6DF2}\x{6DF3}\x{6DF4}\x{6DF5}\x{6DF6}\x{6DF7}\x{6DF8}' - . '\x{6DF9}\x{6DFA}\x{6DFB}\x{6DFC}\x{6DFD}\x{6E00}\x{6E03}\x{6E04}\x{6E05}' - . '\x{6E07}\x{6E08}\x{6E09}\x{6E0A}\x{6E0B}\x{6E0C}\x{6E0D}\x{6E0E}\x{6E0F}' - . '\x{6E10}\x{6E11}\x{6E14}\x{6E15}\x{6E16}\x{6E17}\x{6E19}\x{6E1A}\x{6E1B}' - . '\x{6E1C}\x{6E1D}\x{6E1E}\x{6E1F}\x{6E20}\x{6E21}\x{6E22}\x{6E23}\x{6E24}' - . '\x{6E25}\x{6E26}\x{6E27}\x{6E28}\x{6E29}\x{6E2B}\x{6E2C}\x{6E2D}\x{6E2E}' - . '\x{6E2F}\x{6E30}\x{6E31}\x{6E32}\x{6E33}\x{6E34}\x{6E35}\x{6E36}\x{6E37}' - . '\x{6E38}\x{6E39}\x{6E3A}\x{6E3B}\x{6E3C}\x{6E3D}\x{6E3E}\x{6E3F}\x{6E40}' - . '\x{6E41}\x{6E42}\x{6E43}\x{6E44}\x{6E45}\x{6E46}\x{6E47}\x{6E48}\x{6E49}' - . '\x{6E4A}\x{6E4B}\x{6E4D}\x{6E4E}\x{6E4F}\x{6E50}\x{6E51}\x{6E52}\x{6E53}' - . '\x{6E54}\x{6E55}\x{6E56}\x{6E57}\x{6E58}\x{6E59}\x{6E5A}\x{6E5B}\x{6E5C}' - . '\x{6E5D}\x{6E5E}\x{6E5F}\x{6E60}\x{6E61}\x{6E62}\x{6E63}\x{6E64}\x{6E65}' - . '\x{6E66}\x{6E67}\x{6E68}\x{6E69}\x{6E6A}\x{6E6B}\x{6E6D}\x{6E6E}\x{6E6F}' - . '\x{6E70}\x{6E71}\x{6E72}\x{6E73}\x{6E74}\x{6E75}\x{6E77}\x{6E78}\x{6E79}' - . '\x{6E7E}\x{6E7F}\x{6E80}\x{6E81}\x{6E82}\x{6E83}\x{6E84}\x{6E85}\x{6E86}' - . '\x{6E87}\x{6E88}\x{6E89}\x{6E8A}\x{6E8D}\x{6E8E}\x{6E8F}\x{6E90}\x{6E91}' - . '\x{6E92}\x{6E93}\x{6E94}\x{6E96}\x{6E97}\x{6E98}\x{6E99}\x{6E9A}\x{6E9B}' - . '\x{6E9C}\x{6E9D}\x{6E9E}\x{6E9F}\x{6EA0}\x{6EA1}\x{6EA2}\x{6EA3}\x{6EA4}' - . '\x{6EA5}\x{6EA6}\x{6EA7}\x{6EA8}\x{6EA9}\x{6EAA}\x{6EAB}\x{6EAC}\x{6EAD}' - . '\x{6EAE}\x{6EAF}\x{6EB0}\x{6EB1}\x{6EB2}\x{6EB3}\x{6EB4}\x{6EB5}\x{6EB6}' - . '\x{6EB7}\x{6EB8}\x{6EB9}\x{6EBA}\x{6EBB}\x{6EBC}\x{6EBD}\x{6EBE}\x{6EBF}' - . '\x{6EC0}\x{6EC1}\x{6EC2}\x{6EC3}\x{6EC4}\x{6EC5}\x{6EC6}\x{6EC7}\x{6EC8}' - . '\x{6EC9}\x{6ECA}\x{6ECB}\x{6ECC}\x{6ECD}\x{6ECE}\x{6ECF}\x{6ED0}\x{6ED1}' - . '\x{6ED2}\x{6ED3}\x{6ED4}\x{6ED5}\x{6ED6}\x{6ED7}\x{6ED8}\x{6ED9}\x{6EDA}' - . '\x{6EDC}\x{6EDE}\x{6EDF}\x{6EE0}\x{6EE1}\x{6EE2}\x{6EE4}\x{6EE5}\x{6EE6}' - . '\x{6EE7}\x{6EE8}\x{6EE9}\x{6EEA}\x{6EEB}\x{6EEC}\x{6EED}\x{6EEE}\x{6EEF}' - . '\x{6EF0}\x{6EF1}\x{6EF2}\x{6EF3}\x{6EF4}\x{6EF5}\x{6EF6}\x{6EF7}\x{6EF8}' - . '\x{6EF9}\x{6EFA}\x{6EFB}\x{6EFC}\x{6EFD}\x{6EFE}\x{6EFF}\x{6F00}\x{6F01}' - . '\x{6F02}\x{6F03}\x{6F05}\x{6F06}\x{6F07}\x{6F08}\x{6F09}\x{6F0A}\x{6F0C}' - . '\x{6F0D}\x{6F0E}\x{6F0F}\x{6F10}\x{6F11}\x{6F12}\x{6F13}\x{6F14}\x{6F15}' - . '\x{6F16}\x{6F17}\x{6F18}\x{6F19}\x{6F1A}\x{6F1B}\x{6F1C}\x{6F1D}\x{6F1E}' - . '\x{6F1F}\x{6F20}\x{6F21}\x{6F22}\x{6F23}\x{6F24}\x{6F25}\x{6F26}\x{6F27}' - . '\x{6F28}\x{6F29}\x{6F2A}\x{6F2B}\x{6F2C}\x{6F2D}\x{6F2E}\x{6F2F}\x{6F30}' - . '\x{6F31}\x{6F32}\x{6F33}\x{6F34}\x{6F35}\x{6F36}\x{6F37}\x{6F38}\x{6F39}' - . '\x{6F3A}\x{6F3B}\x{6F3C}\x{6F3D}\x{6F3E}\x{6F3F}\x{6F40}\x{6F41}\x{6F43}' - . '\x{6F44}\x{6F45}\x{6F46}\x{6F47}\x{6F49}\x{6F4B}\x{6F4C}\x{6F4D}\x{6F4E}' - . '\x{6F4F}\x{6F50}\x{6F51}\x{6F52}\x{6F53}\x{6F54}\x{6F55}\x{6F56}\x{6F57}' - . '\x{6F58}\x{6F59}\x{6F5A}\x{6F5B}\x{6F5C}\x{6F5D}\x{6F5E}\x{6F5F}\x{6F60}' - . '\x{6F61}\x{6F62}\x{6F63}\x{6F64}\x{6F65}\x{6F66}\x{6F67}\x{6F68}\x{6F69}' - . '\x{6F6A}\x{6F6B}\x{6F6C}\x{6F6D}\x{6F6E}\x{6F6F}\x{6F70}\x{6F71}\x{6F72}' - . '\x{6F73}\x{6F74}\x{6F75}\x{6F76}\x{6F77}\x{6F78}\x{6F7A}\x{6F7B}\x{6F7C}' - . '\x{6F7D}\x{6F7E}\x{6F7F}\x{6F80}\x{6F81}\x{6F82}\x{6F83}\x{6F84}\x{6F85}' - . '\x{6F86}\x{6F87}\x{6F88}\x{6F89}\x{6F8A}\x{6F8B}\x{6F8C}\x{6F8D}\x{6F8E}' - . '\x{6F8F}\x{6F90}\x{6F91}\x{6F92}\x{6F93}\x{6F94}\x{6F95}\x{6F96}\x{6F97}' - . '\x{6F99}\x{6F9B}\x{6F9C}\x{6F9D}\x{6F9E}\x{6FA0}\x{6FA1}\x{6FA2}\x{6FA3}' - . '\x{6FA4}\x{6FA5}\x{6FA6}\x{6FA7}\x{6FA8}\x{6FA9}\x{6FAA}\x{6FAB}\x{6FAC}' - . '\x{6FAD}\x{6FAE}\x{6FAF}\x{6FB0}\x{6FB1}\x{6FB2}\x{6FB3}\x{6FB4}\x{6FB5}' - . '\x{6FB6}\x{6FB8}\x{6FB9}\x{6FBA}\x{6FBB}\x{6FBC}\x{6FBD}\x{6FBE}\x{6FBF}' - . '\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC4}\x{6FC6}\x{6FC7}\x{6FC8}\x{6FC9}' - . '\x{6FCA}\x{6FCB}\x{6FCC}\x{6FCD}\x{6FCE}\x{6FCF}\x{6FD1}\x{6FD2}\x{6FD4}' - . '\x{6FD5}\x{6FD6}\x{6FD7}\x{6FD8}\x{6FD9}\x{6FDA}\x{6FDB}\x{6FDC}\x{6FDD}' - . '\x{6FDE}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE2}\x{6FE3}\x{6FE4}\x{6FE5}\x{6FE6}' - . '\x{6FE7}\x{6FE8}\x{6FE9}\x{6FEA}\x{6FEB}\x{6FEC}\x{6FED}\x{6FEE}\x{6FEF}' - . '\x{6FF0}\x{6FF1}\x{6FF2}\x{6FF3}\x{6FF4}\x{6FF6}\x{6FF7}\x{6FF8}\x{6FF9}' - . '\x{6FFA}\x{6FFB}\x{6FFC}\x{6FFE}\x{6FFF}\x{7000}\x{7001}\x{7002}\x{7003}' - . '\x{7004}\x{7005}\x{7006}\x{7007}\x{7008}\x{7009}\x{700A}\x{700B}\x{700C}' - . '\x{700D}\x{700E}\x{700F}\x{7011}\x{7012}\x{7014}\x{7015}\x{7016}\x{7017}' - . '\x{7018}\x{7019}\x{701A}\x{701B}\x{701C}\x{701D}\x{701F}\x{7020}\x{7021}' - . '\x{7022}\x{7023}\x{7024}\x{7025}\x{7026}\x{7027}\x{7028}\x{7029}\x{702A}' - . '\x{702B}\x{702C}\x{702D}\x{702E}\x{702F}\x{7030}\x{7031}\x{7032}\x{7033}' - . '\x{7034}\x{7035}\x{7036}\x{7037}\x{7038}\x{7039}\x{703A}\x{703B}\x{703C}' - . '\x{703D}\x{703E}\x{703F}\x{7040}\x{7041}\x{7042}\x{7043}\x{7044}\x{7045}' - . '\x{7046}\x{7048}\x{7049}\x{704A}\x{704C}\x{704D}\x{704F}\x{7050}\x{7051}' - . '\x{7052}\x{7053}\x{7054}\x{7055}\x{7056}\x{7057}\x{7058}\x{7059}\x{705A}' - . '\x{705B}\x{705C}\x{705D}\x{705E}\x{705F}\x{7060}\x{7061}\x{7062}\x{7063}' - . '\x{7064}\x{7065}\x{7066}\x{7067}\x{7068}\x{7069}\x{706A}\x{706B}\x{706C}' - . '\x{706D}\x{706E}\x{706F}\x{7070}\x{7071}\x{7074}\x{7075}\x{7076}\x{7077}' - . '\x{7078}\x{7079}\x{707A}\x{707C}\x{707D}\x{707E}\x{707F}\x{7080}\x{7082}' - . '\x{7083}\x{7084}\x{7085}\x{7086}\x{7087}\x{7088}\x{7089}\x{708A}\x{708B}' - . '\x{708C}\x{708E}\x{708F}\x{7090}\x{7091}\x{7092}\x{7093}\x{7094}\x{7095}' - . '\x{7096}\x{7098}\x{7099}\x{709A}\x{709C}\x{709D}\x{709E}\x{709F}\x{70A0}' - . '\x{70A1}\x{70A2}\x{70A3}\x{70A4}\x{70A5}\x{70A6}\x{70A7}\x{70A8}\x{70A9}' - . '\x{70AB}\x{70AC}\x{70AD}\x{70AE}\x{70AF}\x{70B0}\x{70B1}\x{70B3}\x{70B4}' - . '\x{70B5}\x{70B7}\x{70B8}\x{70B9}\x{70BA}\x{70BB}\x{70BC}\x{70BD}\x{70BE}' - . '\x{70BF}\x{70C0}\x{70C1}\x{70C2}\x{70C3}\x{70C4}\x{70C5}\x{70C6}\x{70C7}' - . '\x{70C8}\x{70C9}\x{70CA}\x{70CB}\x{70CC}\x{70CD}\x{70CE}\x{70CF}\x{70D0}' - . '\x{70D1}\x{70D2}\x{70D3}\x{70D4}\x{70D6}\x{70D7}\x{70D8}\x{70D9}\x{70DA}' - . '\x{70DB}\x{70DC}\x{70DD}\x{70DE}\x{70DF}\x{70E0}\x{70E1}\x{70E2}\x{70E3}' - . '\x{70E4}\x{70E5}\x{70E6}\x{70E7}\x{70E8}\x{70E9}\x{70EA}\x{70EB}\x{70EC}' - . '\x{70ED}\x{70EE}\x{70EF}\x{70F0}\x{70F1}\x{70F2}\x{70F3}\x{70F4}\x{70F5}' - . '\x{70F6}\x{70F7}\x{70F8}\x{70F9}\x{70FA}\x{70FB}\x{70FC}\x{70FD}\x{70FF}' - . '\x{7100}\x{7101}\x{7102}\x{7103}\x{7104}\x{7105}\x{7106}\x{7107}\x{7109}' - . '\x{710A}\x{710B}\x{710C}\x{710D}\x{710E}\x{710F}\x{7110}\x{7111}\x{7112}' - . '\x{7113}\x{7115}\x{7116}\x{7117}\x{7118}\x{7119}\x{711A}\x{711B}\x{711C}' - . '\x{711D}\x{711E}\x{711F}\x{7120}\x{7121}\x{7122}\x{7123}\x{7125}\x{7126}' - . '\x{7127}\x{7128}\x{7129}\x{712A}\x{712B}\x{712C}\x{712D}\x{712E}\x{712F}' - . '\x{7130}\x{7131}\x{7132}\x{7135}\x{7136}\x{7137}\x{7138}\x{7139}\x{713A}' - . '\x{713B}\x{713D}\x{713E}\x{713F}\x{7140}\x{7141}\x{7142}\x{7143}\x{7144}' - . '\x{7145}\x{7146}\x{7147}\x{7148}\x{7149}\x{714A}\x{714B}\x{714C}\x{714D}' - . '\x{714E}\x{714F}\x{7150}\x{7151}\x{7152}\x{7153}\x{7154}\x{7156}\x{7158}' - . '\x{7159}\x{715A}\x{715B}\x{715C}\x{715D}\x{715E}\x{715F}\x{7160}\x{7161}' - . '\x{7162}\x{7163}\x{7164}\x{7165}\x{7166}\x{7167}\x{7168}\x{7169}\x{716A}' - . '\x{716C}\x{716E}\x{716F}\x{7170}\x{7171}\x{7172}\x{7173}\x{7174}\x{7175}' - . '\x{7176}\x{7177}\x{7178}\x{7179}\x{717A}\x{717B}\x{717C}\x{717D}\x{717E}' - . '\x{717F}\x{7180}\x{7181}\x{7182}\x{7183}\x{7184}\x{7185}\x{7186}\x{7187}' - . '\x{7188}\x{7189}\x{718A}\x{718B}\x{718C}\x{718E}\x{718F}\x{7190}\x{7191}' - . '\x{7192}\x{7193}\x{7194}\x{7195}\x{7197}\x{7198}\x{7199}\x{719A}\x{719B}' - . '\x{719C}\x{719D}\x{719E}\x{719F}\x{71A0}\x{71A1}\x{71A2}\x{71A3}\x{71A4}' - . '\x{71A5}\x{71A7}\x{71A8}\x{71A9}\x{71AA}\x{71AC}\x{71AD}\x{71AE}\x{71AF}' - . '\x{71B0}\x{71B1}\x{71B2}\x{71B3}\x{71B4}\x{71B5}\x{71B7}\x{71B8}\x{71B9}' - . '\x{71BA}\x{71BB}\x{71BC}\x{71BD}\x{71BE}\x{71BF}\x{71C0}\x{71C1}\x{71C2}' - . '\x{71C3}\x{71C4}\x{71C5}\x{71C6}\x{71C7}\x{71C8}\x{71C9}\x{71CA}\x{71CB}' - . '\x{71CD}\x{71CE}\x{71CF}\x{71D0}\x{71D1}\x{71D2}\x{71D4}\x{71D5}\x{71D6}' - . '\x{71D7}\x{71D8}\x{71D9}\x{71DA}\x{71DB}\x{71DC}\x{71DD}\x{71DE}\x{71DF}' - . '\x{71E0}\x{71E1}\x{71E2}\x{71E3}\x{71E4}\x{71E5}\x{71E6}\x{71E7}\x{71E8}' - . '\x{71E9}\x{71EA}\x{71EB}\x{71EC}\x{71ED}\x{71EE}\x{71EF}\x{71F0}\x{71F1}' - . '\x{71F2}\x{71F4}\x{71F5}\x{71F6}\x{71F7}\x{71F8}\x{71F9}\x{71FB}\x{71FC}' - . '\x{71FD}\x{71FE}\x{71FF}\x{7201}\x{7202}\x{7203}\x{7204}\x{7205}\x{7206}' - . '\x{7207}\x{7208}\x{7209}\x{720A}\x{720C}\x{720D}\x{720E}\x{720F}\x{7210}' - . '\x{7212}\x{7213}\x{7214}\x{7216}\x{7218}\x{7219}\x{721A}\x{721B}\x{721C}' - . '\x{721D}\x{721E}\x{721F}\x{7221}\x{7222}\x{7223}\x{7226}\x{7227}\x{7228}' - . '\x{7229}\x{722A}\x{722B}\x{722C}\x{722D}\x{722E}\x{7230}\x{7231}\x{7232}' - . '\x{7233}\x{7235}\x{7236}\x{7237}\x{7238}\x{7239}\x{723A}\x{723B}\x{723C}' - . '\x{723D}\x{723E}\x{723F}\x{7240}\x{7241}\x{7242}\x{7243}\x{7244}\x{7246}' - . '\x{7247}\x{7248}\x{7249}\x{724A}\x{724B}\x{724C}\x{724D}\x{724F}\x{7251}' - . '\x{7252}\x{7253}\x{7254}\x{7256}\x{7257}\x{7258}\x{7259}\x{725A}\x{725B}' - . '\x{725C}\x{725D}\x{725E}\x{725F}\x{7260}\x{7261}\x{7262}\x{7263}\x{7264}' - . '\x{7265}\x{7266}\x{7267}\x{7268}\x{7269}\x{726A}\x{726B}\x{726C}\x{726D}' - . '\x{726E}\x{726F}\x{7270}\x{7271}\x{7272}\x{7273}\x{7274}\x{7275}\x{7276}' - . '\x{7277}\x{7278}\x{7279}\x{727A}\x{727B}\x{727C}\x{727D}\x{727E}\x{727F}' - . '\x{7280}\x{7281}\x{7282}\x{7283}\x{7284}\x{7285}\x{7286}\x{7287}\x{7288}' - . '\x{7289}\x{728A}\x{728B}\x{728C}\x{728D}\x{728E}\x{728F}\x{7290}\x{7291}' - . '\x{7292}\x{7293}\x{7294}\x{7295}\x{7296}\x{7297}\x{7298}\x{7299}\x{729A}' - . '\x{729B}\x{729C}\x{729D}\x{729E}\x{729F}\x{72A1}\x{72A2}\x{72A3}\x{72A4}' - . '\x{72A5}\x{72A6}\x{72A7}\x{72A8}\x{72A9}\x{72AA}\x{72AC}\x{72AD}\x{72AE}' - . '\x{72AF}\x{72B0}\x{72B1}\x{72B2}\x{72B3}\x{72B4}\x{72B5}\x{72B6}\x{72B7}' - . '\x{72B8}\x{72B9}\x{72BA}\x{72BB}\x{72BC}\x{72BD}\x{72BF}\x{72C0}\x{72C1}' - . '\x{72C2}\x{72C3}\x{72C4}\x{72C5}\x{72C6}\x{72C7}\x{72C8}\x{72C9}\x{72CA}' - . '\x{72CB}\x{72CC}\x{72CD}\x{72CE}\x{72CF}\x{72D0}\x{72D1}\x{72D2}\x{72D3}' - . '\x{72D4}\x{72D5}\x{72D6}\x{72D7}\x{72D8}\x{72D9}\x{72DA}\x{72DB}\x{72DC}' - . '\x{72DD}\x{72DE}\x{72DF}\x{72E0}\x{72E1}\x{72E2}\x{72E3}\x{72E4}\x{72E5}' - . '\x{72E6}\x{72E7}\x{72E8}\x{72E9}\x{72EA}\x{72EB}\x{72EC}\x{72ED}\x{72EE}' - . '\x{72EF}\x{72F0}\x{72F1}\x{72F2}\x{72F3}\x{72F4}\x{72F5}\x{72F6}\x{72F7}' - . '\x{72F8}\x{72F9}\x{72FA}\x{72FB}\x{72FC}\x{72FD}\x{72FE}\x{72FF}\x{7300}' - . '\x{7301}\x{7303}\x{7304}\x{7305}\x{7306}\x{7307}\x{7308}\x{7309}\x{730A}' - . '\x{730B}\x{730C}\x{730D}\x{730E}\x{730F}\x{7311}\x{7312}\x{7313}\x{7314}' - . '\x{7315}\x{7316}\x{7317}\x{7318}\x{7319}\x{731A}\x{731B}\x{731C}\x{731D}' - . '\x{731E}\x{7320}\x{7321}\x{7322}\x{7323}\x{7324}\x{7325}\x{7326}\x{7327}' - . '\x{7329}\x{732A}\x{732B}\x{732C}\x{732D}\x{732E}\x{7330}\x{7331}\x{7332}' - . '\x{7333}\x{7334}\x{7335}\x{7336}\x{7337}\x{7338}\x{7339}\x{733A}\x{733B}' - . '\x{733C}\x{733D}\x{733E}\x{733F}\x{7340}\x{7341}\x{7342}\x{7343}\x{7344}' - . '\x{7345}\x{7346}\x{7347}\x{7348}\x{7349}\x{734A}\x{734B}\x{734C}\x{734D}' - . '\x{734E}\x{7350}\x{7351}\x{7352}\x{7354}\x{7355}\x{7356}\x{7357}\x{7358}' - . '\x{7359}\x{735A}\x{735B}\x{735C}\x{735D}\x{735E}\x{735F}\x{7360}\x{7361}' - . '\x{7362}\x{7364}\x{7365}\x{7366}\x{7367}\x{7368}\x{7369}\x{736A}\x{736B}' - . '\x{736C}\x{736D}\x{736E}\x{736F}\x{7370}\x{7371}\x{7372}\x{7373}\x{7374}' - . '\x{7375}\x{7376}\x{7377}\x{7378}\x{7379}\x{737A}\x{737B}\x{737C}\x{737D}' - . '\x{737E}\x{737F}\x{7380}\x{7381}\x{7382}\x{7383}\x{7384}\x{7385}\x{7386}' - . '\x{7387}\x{7388}\x{7389}\x{738A}\x{738B}\x{738C}\x{738D}\x{738E}\x{738F}' - . '\x{7390}\x{7391}\x{7392}\x{7393}\x{7394}\x{7395}\x{7396}\x{7397}\x{7398}' - . '\x{7399}\x{739A}\x{739B}\x{739D}\x{739E}\x{739F}\x{73A0}\x{73A1}\x{73A2}' - . '\x{73A3}\x{73A4}\x{73A5}\x{73A6}\x{73A7}\x{73A8}\x{73A9}\x{73AA}\x{73AB}' - . '\x{73AC}\x{73AD}\x{73AE}\x{73AF}\x{73B0}\x{73B1}\x{73B2}\x{73B3}\x{73B4}' - . '\x{73B5}\x{73B6}\x{73B7}\x{73B8}\x{73B9}\x{73BA}\x{73BB}\x{73BC}\x{73BD}' - . '\x{73BE}\x{73BF}\x{73C0}\x{73C2}\x{73C3}\x{73C4}\x{73C5}\x{73C6}\x{73C7}' - . '\x{73C8}\x{73C9}\x{73CA}\x{73CB}\x{73CC}\x{73CD}\x{73CE}\x{73CF}\x{73D0}' - . '\x{73D1}\x{73D2}\x{73D3}\x{73D4}\x{73D5}\x{73D6}\x{73D7}\x{73D8}\x{73D9}' - . '\x{73DA}\x{73DB}\x{73DC}\x{73DD}\x{73DE}\x{73DF}\x{73E0}\x{73E2}\x{73E3}' - . '\x{73E5}\x{73E6}\x{73E7}\x{73E8}\x{73E9}\x{73EA}\x{73EB}\x{73EC}\x{73ED}' - . '\x{73EE}\x{73EF}\x{73F0}\x{73F1}\x{73F2}\x{73F4}\x{73F5}\x{73F6}\x{73F7}' - . '\x{73F8}\x{73F9}\x{73FA}\x{73FC}\x{73FD}\x{73FE}\x{73FF}\x{7400}\x{7401}' - . '\x{7402}\x{7403}\x{7404}\x{7405}\x{7406}\x{7407}\x{7408}\x{7409}\x{740A}' - . '\x{740B}\x{740C}\x{740D}\x{740E}\x{740F}\x{7410}\x{7411}\x{7412}\x{7413}' - . '\x{7414}\x{7415}\x{7416}\x{7417}\x{7419}\x{741A}\x{741B}\x{741C}\x{741D}' - . '\x{741E}\x{741F}\x{7420}\x{7421}\x{7422}\x{7423}\x{7424}\x{7425}\x{7426}' - . '\x{7427}\x{7428}\x{7429}\x{742A}\x{742B}\x{742C}\x{742D}\x{742E}\x{742F}' - . '\x{7430}\x{7431}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{7437}\x{7438}' - . '\x{743A}\x{743B}\x{743C}\x{743D}\x{743F}\x{7440}\x{7441}\x{7442}\x{7443}' - . '\x{7444}\x{7445}\x{7446}\x{7448}\x{744A}\x{744B}\x{744C}\x{744D}\x{744E}' - . '\x{744F}\x{7450}\x{7451}\x{7452}\x{7453}\x{7454}\x{7455}\x{7456}\x{7457}' - . '\x{7459}\x{745A}\x{745B}\x{745C}\x{745D}\x{745E}\x{745F}\x{7461}\x{7462}' - . '\x{7463}\x{7464}\x{7465}\x{7466}\x{7467}\x{7468}\x{7469}\x{746A}\x{746B}' - . '\x{746C}\x{746D}\x{746E}\x{746F}\x{7470}\x{7471}\x{7472}\x{7473}\x{7474}' - . '\x{7475}\x{7476}\x{7477}\x{7478}\x{7479}\x{747A}\x{747C}\x{747D}\x{747E}' - . '\x{747F}\x{7480}\x{7481}\x{7482}\x{7483}\x{7485}\x{7486}\x{7487}\x{7488}' - . '\x{7489}\x{748A}\x{748B}\x{748C}\x{748D}\x{748E}\x{748F}\x{7490}\x{7491}' - . '\x{7492}\x{7493}\x{7494}\x{7495}\x{7497}\x{7498}\x{7499}\x{749A}\x{749B}' - . '\x{749C}\x{749E}\x{749F}\x{74A0}\x{74A1}\x{74A3}\x{74A4}\x{74A5}\x{74A6}' - . '\x{74A7}\x{74A8}\x{74A9}\x{74AA}\x{74AB}\x{74AC}\x{74AD}\x{74AE}\x{74AF}' - . '\x{74B0}\x{74B1}\x{74B2}\x{74B3}\x{74B4}\x{74B5}\x{74B6}\x{74B7}\x{74B8}' - . '\x{74B9}\x{74BA}\x{74BB}\x{74BC}\x{74BD}\x{74BE}\x{74BF}\x{74C0}\x{74C1}' - . '\x{74C2}\x{74C3}\x{74C4}\x{74C5}\x{74C6}\x{74CA}\x{74CB}\x{74CD}\x{74CE}' - . '\x{74CF}\x{74D0}\x{74D1}\x{74D2}\x{74D3}\x{74D4}\x{74D5}\x{74D6}\x{74D7}' - . '\x{74D8}\x{74D9}\x{74DA}\x{74DB}\x{74DC}\x{74DD}\x{74DE}\x{74DF}\x{74E0}' - . '\x{74E1}\x{74E2}\x{74E3}\x{74E4}\x{74E5}\x{74E6}\x{74E7}\x{74E8}\x{74E9}' - . '\x{74EA}\x{74EC}\x{74ED}\x{74EE}\x{74EF}\x{74F0}\x{74F1}\x{74F2}\x{74F3}' - . '\x{74F4}\x{74F5}\x{74F6}\x{74F7}\x{74F8}\x{74F9}\x{74FA}\x{74FB}\x{74FC}' - . '\x{74FD}\x{74FE}\x{74FF}\x{7500}\x{7501}\x{7502}\x{7503}\x{7504}\x{7505}' - . '\x{7506}\x{7507}\x{7508}\x{7509}\x{750A}\x{750B}\x{750C}\x{750D}\x{750F}' - . '\x{7510}\x{7511}\x{7512}\x{7513}\x{7514}\x{7515}\x{7516}\x{7517}\x{7518}' - . '\x{7519}\x{751A}\x{751B}\x{751C}\x{751D}\x{751E}\x{751F}\x{7521}\x{7522}' - . '\x{7523}\x{7524}\x{7525}\x{7526}\x{7527}\x{7528}\x{7529}\x{752A}\x{752B}' - . '\x{752C}\x{752D}\x{752E}\x{752F}\x{7530}\x{7531}\x{7532}\x{7533}\x{7535}' - . '\x{7536}\x{7537}\x{7538}\x{7539}\x{753A}\x{753B}\x{753C}\x{753D}\x{753E}' - . '\x{753F}\x{7540}\x{7542}\x{7543}\x{7544}\x{7545}\x{7546}\x{7547}\x{7548}' - . '\x{7549}\x{754B}\x{754C}\x{754D}\x{754E}\x{754F}\x{7550}\x{7551}\x{7553}' - . '\x{7554}\x{7556}\x{7557}\x{7558}\x{7559}\x{755A}\x{755B}\x{755C}\x{755D}' - . '\x{755F}\x{7560}\x{7562}\x{7563}\x{7564}\x{7565}\x{7566}\x{7567}\x{7568}' - . '\x{7569}\x{756A}\x{756B}\x{756C}\x{756D}\x{756E}\x{756F}\x{7570}\x{7572}' - . '\x{7574}\x{7575}\x{7576}\x{7577}\x{7578}\x{7579}\x{757C}\x{757D}\x{757E}' - . '\x{757F}\x{7580}\x{7581}\x{7582}\x{7583}\x{7584}\x{7586}\x{7587}\x{7588}' - . '\x{7589}\x{758A}\x{758B}\x{758C}\x{758D}\x{758F}\x{7590}\x{7591}\x{7592}' - . '\x{7593}\x{7594}\x{7595}\x{7596}\x{7597}\x{7598}\x{7599}\x{759A}\x{759B}' - . '\x{759C}\x{759D}\x{759E}\x{759F}\x{75A0}\x{75A1}\x{75A2}\x{75A3}\x{75A4}' - . '\x{75A5}\x{75A6}\x{75A7}\x{75A8}\x{75AA}\x{75AB}\x{75AC}\x{75AD}\x{75AE}' - . '\x{75AF}\x{75B0}\x{75B1}\x{75B2}\x{75B3}\x{75B4}\x{75B5}\x{75B6}\x{75B8}' - . '\x{75B9}\x{75BA}\x{75BB}\x{75BC}\x{75BD}\x{75BE}\x{75BF}\x{75C0}\x{75C1}' - . '\x{75C2}\x{75C3}\x{75C4}\x{75C5}\x{75C6}\x{75C7}\x{75C8}\x{75C9}\x{75CA}' - . '\x{75CB}\x{75CC}\x{75CD}\x{75CE}\x{75CF}\x{75D0}\x{75D1}\x{75D2}\x{75D3}' - . '\x{75D4}\x{75D5}\x{75D6}\x{75D7}\x{75D8}\x{75D9}\x{75DA}\x{75DB}\x{75DD}' - . '\x{75DE}\x{75DF}\x{75E0}\x{75E1}\x{75E2}\x{75E3}\x{75E4}\x{75E5}\x{75E6}' - . '\x{75E7}\x{75E8}\x{75EA}\x{75EB}\x{75EC}\x{75ED}\x{75EF}\x{75F0}\x{75F1}' - . '\x{75F2}\x{75F3}\x{75F4}\x{75F5}\x{75F6}\x{75F7}\x{75F8}\x{75F9}\x{75FA}' - . '\x{75FB}\x{75FC}\x{75FD}\x{75FE}\x{75FF}\x{7600}\x{7601}\x{7602}\x{7603}' - . '\x{7604}\x{7605}\x{7606}\x{7607}\x{7608}\x{7609}\x{760A}\x{760B}\x{760C}' - . '\x{760D}\x{760E}\x{760F}\x{7610}\x{7611}\x{7612}\x{7613}\x{7614}\x{7615}' - . '\x{7616}\x{7617}\x{7618}\x{7619}\x{761A}\x{761B}\x{761C}\x{761D}\x{761E}' - . '\x{761F}\x{7620}\x{7621}\x{7622}\x{7623}\x{7624}\x{7625}\x{7626}\x{7627}' - . '\x{7628}\x{7629}\x{762A}\x{762B}\x{762D}\x{762E}\x{762F}\x{7630}\x{7631}' - . '\x{7632}\x{7633}\x{7634}\x{7635}\x{7636}\x{7637}\x{7638}\x{7639}\x{763A}' - . '\x{763B}\x{763C}\x{763D}\x{763E}\x{763F}\x{7640}\x{7641}\x{7642}\x{7643}' - . '\x{7646}\x{7647}\x{7648}\x{7649}\x{764A}\x{764B}\x{764C}\x{764D}\x{764F}' - . '\x{7650}\x{7652}\x{7653}\x{7654}\x{7656}\x{7657}\x{7658}\x{7659}\x{765A}' - . '\x{765B}\x{765C}\x{765D}\x{765E}\x{765F}\x{7660}\x{7661}\x{7662}\x{7663}' - . '\x{7664}\x{7665}\x{7666}\x{7667}\x{7668}\x{7669}\x{766A}\x{766B}\x{766C}' - . '\x{766D}\x{766E}\x{766F}\x{7670}\x{7671}\x{7672}\x{7674}\x{7675}\x{7676}' - . '\x{7677}\x{7678}\x{7679}\x{767B}\x{767C}\x{767D}\x{767E}\x{767F}\x{7680}' - . '\x{7681}\x{7682}\x{7683}\x{7684}\x{7685}\x{7686}\x{7687}\x{7688}\x{7689}' - . '\x{768A}\x{768B}\x{768C}\x{768E}\x{768F}\x{7690}\x{7691}\x{7692}\x{7693}' - . '\x{7694}\x{7695}\x{7696}\x{7697}\x{7698}\x{7699}\x{769A}\x{769B}\x{769C}' - . '\x{769D}\x{769E}\x{769F}\x{76A0}\x{76A3}\x{76A4}\x{76A6}\x{76A7}\x{76A9}' - . '\x{76AA}\x{76AB}\x{76AC}\x{76AD}\x{76AE}\x{76AF}\x{76B0}\x{76B1}\x{76B2}' - . '\x{76B4}\x{76B5}\x{76B7}\x{76B8}\x{76BA}\x{76BB}\x{76BC}\x{76BD}\x{76BE}' - . '\x{76BF}\x{76C0}\x{76C2}\x{76C3}\x{76C4}\x{76C5}\x{76C6}\x{76C7}\x{76C8}' - . '\x{76C9}\x{76CA}\x{76CD}\x{76CE}\x{76CF}\x{76D0}\x{76D1}\x{76D2}\x{76D3}' - . '\x{76D4}\x{76D5}\x{76D6}\x{76D7}\x{76D8}\x{76DA}\x{76DB}\x{76DC}\x{76DD}' - . '\x{76DE}\x{76DF}\x{76E0}\x{76E1}\x{76E2}\x{76E3}\x{76E4}\x{76E5}\x{76E6}' - . '\x{76E7}\x{76E8}\x{76E9}\x{76EA}\x{76EC}\x{76ED}\x{76EE}\x{76EF}\x{76F0}' - . '\x{76F1}\x{76F2}\x{76F3}\x{76F4}\x{76F5}\x{76F6}\x{76F7}\x{76F8}\x{76F9}' - . '\x{76FA}\x{76FB}\x{76FC}\x{76FD}\x{76FE}\x{76FF}\x{7701}\x{7703}\x{7704}' - . '\x{7705}\x{7706}\x{7707}\x{7708}\x{7709}\x{770A}\x{770B}\x{770C}\x{770D}' - . '\x{770F}\x{7710}\x{7711}\x{7712}\x{7713}\x{7714}\x{7715}\x{7716}\x{7717}' - . '\x{7718}\x{7719}\x{771A}\x{771B}\x{771C}\x{771D}\x{771E}\x{771F}\x{7720}' - . '\x{7722}\x{7723}\x{7725}\x{7726}\x{7727}\x{7728}\x{7729}\x{772A}\x{772C}' - . '\x{772D}\x{772E}\x{772F}\x{7730}\x{7731}\x{7732}\x{7733}\x{7734}\x{7735}' - . '\x{7736}\x{7737}\x{7738}\x{7739}\x{773A}\x{773B}\x{773C}\x{773D}\x{773E}' - . '\x{7740}\x{7741}\x{7743}\x{7744}\x{7745}\x{7746}\x{7747}\x{7748}\x{7749}' - . '\x{774A}\x{774B}\x{774C}\x{774D}\x{774E}\x{774F}\x{7750}\x{7751}\x{7752}' - . '\x{7753}\x{7754}\x{7755}\x{7756}\x{7757}\x{7758}\x{7759}\x{775A}\x{775B}' - . '\x{775C}\x{775D}\x{775E}\x{775F}\x{7760}\x{7761}\x{7762}\x{7763}\x{7765}' - . '\x{7766}\x{7767}\x{7768}\x{7769}\x{776A}\x{776B}\x{776C}\x{776D}\x{776E}' - . '\x{776F}\x{7770}\x{7771}\x{7772}\x{7773}\x{7774}\x{7775}\x{7776}\x{7777}' - . '\x{7778}\x{7779}\x{777A}\x{777B}\x{777C}\x{777D}\x{777E}\x{777F}\x{7780}' - . '\x{7781}\x{7782}\x{7783}\x{7784}\x{7785}\x{7786}\x{7787}\x{7788}\x{7789}' - . '\x{778A}\x{778B}\x{778C}\x{778D}\x{778E}\x{778F}\x{7790}\x{7791}\x{7792}' - . '\x{7793}\x{7794}\x{7795}\x{7797}\x{7798}\x{7799}\x{779A}\x{779B}\x{779C}' - . '\x{779D}\x{779E}\x{779F}\x{77A0}\x{77A1}\x{77A2}\x{77A3}\x{77A5}\x{77A6}' - . '\x{77A7}\x{77A8}\x{77A9}\x{77AA}\x{77AB}\x{77AC}\x{77AD}\x{77AE}\x{77AF}' - . '\x{77B0}\x{77B1}\x{77B2}\x{77B3}\x{77B4}\x{77B5}\x{77B6}\x{77B7}\x{77B8}' - . '\x{77B9}\x{77BA}\x{77BB}\x{77BC}\x{77BD}\x{77BF}\x{77C0}\x{77C2}\x{77C3}' - . '\x{77C4}\x{77C5}\x{77C6}\x{77C7}\x{77C8}\x{77C9}\x{77CA}\x{77CB}\x{77CC}' - . '\x{77CD}\x{77CE}\x{77CF}\x{77D0}\x{77D1}\x{77D3}\x{77D4}\x{77D5}\x{77D6}' - . '\x{77D7}\x{77D8}\x{77D9}\x{77DA}\x{77DB}\x{77DC}\x{77DE}\x{77DF}\x{77E0}' - . '\x{77E1}\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E8}\x{77E9}\x{77EA}\x{77EB}' - . '\x{77EC}\x{77ED}\x{77EE}\x{77EF}\x{77F0}\x{77F1}\x{77F2}\x{77F3}\x{77F6}' - . '\x{77F7}\x{77F8}\x{77F9}\x{77FA}\x{77FB}\x{77FC}\x{77FD}\x{77FE}\x{77FF}' - . '\x{7800}\x{7801}\x{7802}\x{7803}\x{7804}\x{7805}\x{7806}\x{7808}\x{7809}' - . '\x{780A}\x{780B}\x{780C}\x{780D}\x{780E}\x{780F}\x{7810}\x{7811}\x{7812}' - . '\x{7813}\x{7814}\x{7815}\x{7816}\x{7817}\x{7818}\x{7819}\x{781A}\x{781B}' - . '\x{781C}\x{781D}\x{781E}\x{781F}\x{7820}\x{7821}\x{7822}\x{7823}\x{7825}' - . '\x{7826}\x{7827}\x{7828}\x{7829}\x{782A}\x{782B}\x{782C}\x{782D}\x{782E}' - . '\x{782F}\x{7830}\x{7831}\x{7832}\x{7833}\x{7834}\x{7835}\x{7837}\x{7838}' - . '\x{7839}\x{783A}\x{783B}\x{783C}\x{783D}\x{783E}\x{7840}\x{7841}\x{7843}' - . '\x{7844}\x{7845}\x{7847}\x{7848}\x{7849}\x{784A}\x{784C}\x{784D}\x{784E}' - . '\x{7850}\x{7851}\x{7852}\x{7853}\x{7854}\x{7855}\x{7856}\x{7857}\x{7858}' - . '\x{7859}\x{785A}\x{785B}\x{785C}\x{785D}\x{785E}\x{785F}\x{7860}\x{7861}' - . '\x{7862}\x{7863}\x{7864}\x{7865}\x{7866}\x{7867}\x{7868}\x{7869}\x{786A}' - . '\x{786B}\x{786C}\x{786D}\x{786E}\x{786F}\x{7870}\x{7871}\x{7872}\x{7873}' - . '\x{7874}\x{7875}\x{7877}\x{7878}\x{7879}\x{787A}\x{787B}\x{787C}\x{787D}' - . '\x{787E}\x{787F}\x{7880}\x{7881}\x{7882}\x{7883}\x{7884}\x{7885}\x{7886}' - . '\x{7887}\x{7889}\x{788A}\x{788B}\x{788C}\x{788D}\x{788E}\x{788F}\x{7890}' - . '\x{7891}\x{7892}\x{7893}\x{7894}\x{7895}\x{7896}\x{7897}\x{7898}\x{7899}' - . '\x{789A}\x{789B}\x{789C}\x{789D}\x{789E}\x{789F}\x{78A0}\x{78A1}\x{78A2}' - . '\x{78A3}\x{78A4}\x{78A5}\x{78A6}\x{78A7}\x{78A8}\x{78A9}\x{78AA}\x{78AB}' - . '\x{78AC}\x{78AD}\x{78AE}\x{78AF}\x{78B0}\x{78B1}\x{78B2}\x{78B3}\x{78B4}' - . '\x{78B5}\x{78B6}\x{78B7}\x{78B8}\x{78B9}\x{78BA}\x{78BB}\x{78BC}\x{78BD}' - . '\x{78BE}\x{78BF}\x{78C0}\x{78C1}\x{78C3}\x{78C4}\x{78C5}\x{78C6}\x{78C8}' - . '\x{78C9}\x{78CA}\x{78CB}\x{78CC}\x{78CD}\x{78CE}\x{78CF}\x{78D0}\x{78D1}' - . '\x{78D3}\x{78D4}\x{78D5}\x{78D6}\x{78D7}\x{78D8}\x{78D9}\x{78DA}\x{78DB}' - . '\x{78DC}\x{78DD}\x{78DE}\x{78DF}\x{78E0}\x{78E1}\x{78E2}\x{78E3}\x{78E4}' - . '\x{78E5}\x{78E6}\x{78E7}\x{78E8}\x{78E9}\x{78EA}\x{78EB}\x{78EC}\x{78ED}' - . '\x{78EE}\x{78EF}\x{78F1}\x{78F2}\x{78F3}\x{78F4}\x{78F5}\x{78F6}\x{78F7}' - . '\x{78F9}\x{78FA}\x{78FB}\x{78FC}\x{78FD}\x{78FE}\x{78FF}\x{7901}\x{7902}' - . '\x{7903}\x{7904}\x{7905}\x{7906}\x{7907}\x{7909}\x{790A}\x{790B}\x{790C}' - . '\x{790E}\x{790F}\x{7910}\x{7911}\x{7912}\x{7913}\x{7914}\x{7916}\x{7917}' - . '\x{7918}\x{7919}\x{791A}\x{791B}\x{791C}\x{791D}\x{791E}\x{7921}\x{7922}' - . '\x{7923}\x{7924}\x{7925}\x{7926}\x{7927}\x{7928}\x{7929}\x{792A}\x{792B}' - . '\x{792C}\x{792D}\x{792E}\x{792F}\x{7930}\x{7931}\x{7933}\x{7934}\x{7935}' - . '\x{7937}\x{7938}\x{7939}\x{793A}\x{793B}\x{793C}\x{793D}\x{793E}\x{793F}' - . '\x{7940}\x{7941}\x{7942}\x{7943}\x{7944}\x{7945}\x{7946}\x{7947}\x{7948}' - . '\x{7949}\x{794A}\x{794B}\x{794C}\x{794D}\x{794E}\x{794F}\x{7950}\x{7951}' - . '\x{7952}\x{7953}\x{7954}\x{7955}\x{7956}\x{7957}\x{7958}\x{795A}\x{795B}' - . '\x{795C}\x{795D}\x{795E}\x{795F}\x{7960}\x{7961}\x{7962}\x{7963}\x{7964}' - . '\x{7965}\x{7966}\x{7967}\x{7968}\x{7969}\x{796A}\x{796B}\x{796D}\x{796F}' - . '\x{7970}\x{7971}\x{7972}\x{7973}\x{7974}\x{7977}\x{7978}\x{7979}\x{797A}' - . '\x{797B}\x{797C}\x{797D}\x{797E}\x{797F}\x{7980}\x{7981}\x{7982}\x{7983}' - . '\x{7984}\x{7985}\x{7988}\x{7989}\x{798A}\x{798B}\x{798C}\x{798D}\x{798E}' - . '\x{798F}\x{7990}\x{7991}\x{7992}\x{7993}\x{7994}\x{7995}\x{7996}\x{7997}' - . '\x{7998}\x{7999}\x{799A}\x{799B}\x{799C}\x{799F}\x{79A0}\x{79A1}\x{79A2}' - . '\x{79A3}\x{79A4}\x{79A5}\x{79A6}\x{79A7}\x{79A8}\x{79AA}\x{79AB}\x{79AC}' - . '\x{79AD}\x{79AE}\x{79AF}\x{79B0}\x{79B1}\x{79B2}\x{79B3}\x{79B4}\x{79B5}' - . '\x{79B6}\x{79B7}\x{79B8}\x{79B9}\x{79BA}\x{79BB}\x{79BD}\x{79BE}\x{79BF}' - . '\x{79C0}\x{79C1}\x{79C2}\x{79C3}\x{79C5}\x{79C6}\x{79C8}\x{79C9}\x{79CA}' - . '\x{79CB}\x{79CD}\x{79CE}\x{79CF}\x{79D0}\x{79D1}\x{79D2}\x{79D3}\x{79D5}' - . '\x{79D6}\x{79D8}\x{79D9}\x{79DA}\x{79DB}\x{79DC}\x{79DD}\x{79DE}\x{79DF}' - . '\x{79E0}\x{79E1}\x{79E2}\x{79E3}\x{79E4}\x{79E5}\x{79E6}\x{79E7}\x{79E8}' - . '\x{79E9}\x{79EA}\x{79EB}\x{79EC}\x{79ED}\x{79EE}\x{79EF}\x{79F0}\x{79F1}' - . '\x{79F2}\x{79F3}\x{79F4}\x{79F5}\x{79F6}\x{79F7}\x{79F8}\x{79F9}\x{79FA}' - . '\x{79FB}\x{79FC}\x{79FD}\x{79FE}\x{79FF}\x{7A00}\x{7A02}\x{7A03}\x{7A04}' - . '\x{7A05}\x{7A06}\x{7A08}\x{7A0A}\x{7A0B}\x{7A0C}\x{7A0D}\x{7A0E}\x{7A0F}' - . '\x{7A10}\x{7A11}\x{7A12}\x{7A13}\x{7A14}\x{7A15}\x{7A16}\x{7A17}\x{7A18}' - . '\x{7A19}\x{7A1A}\x{7A1B}\x{7A1C}\x{7A1D}\x{7A1E}\x{7A1F}\x{7A20}\x{7A21}' - . '\x{7A22}\x{7A23}\x{7A24}\x{7A25}\x{7A26}\x{7A27}\x{7A28}\x{7A29}\x{7A2A}' - . '\x{7A2B}\x{7A2D}\x{7A2E}\x{7A2F}\x{7A30}\x{7A31}\x{7A32}\x{7A33}\x{7A34}' - . '\x{7A35}\x{7A37}\x{7A39}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' - . '\x{7A41}\x{7A42}\x{7A43}\x{7A44}\x{7A45}\x{7A46}\x{7A47}\x{7A48}\x{7A49}' - . '\x{7A4A}\x{7A4B}\x{7A4C}\x{7A4D}\x{7A4E}\x{7A50}\x{7A51}\x{7A52}\x{7A53}' - . '\x{7A54}\x{7A55}\x{7A56}\x{7A57}\x{7A58}\x{7A59}\x{7A5A}\x{7A5B}\x{7A5C}' - . '\x{7A5D}\x{7A5E}\x{7A5F}\x{7A60}\x{7A61}\x{7A62}\x{7A65}\x{7A66}\x{7A67}' - . '\x{7A68}\x{7A69}\x{7A6B}\x{7A6C}\x{7A6D}\x{7A6E}\x{7A70}\x{7A71}\x{7A72}' - . '\x{7A73}\x{7A74}\x{7A75}\x{7A76}\x{7A77}\x{7A78}\x{7A79}\x{7A7A}\x{7A7B}' - . '\x{7A7C}\x{7A7D}\x{7A7E}\x{7A7F}\x{7A80}\x{7A81}\x{7A83}\x{7A84}\x{7A85}' - . '\x{7A86}\x{7A87}\x{7A88}\x{7A89}\x{7A8A}\x{7A8B}\x{7A8C}\x{7A8D}\x{7A8E}' - . '\x{7A8F}\x{7A90}\x{7A91}\x{7A92}\x{7A93}\x{7A94}\x{7A95}\x{7A96}\x{7A97}' - . '\x{7A98}\x{7A99}\x{7A9C}\x{7A9D}\x{7A9E}\x{7A9F}\x{7AA0}\x{7AA1}\x{7AA2}' - . '\x{7AA3}\x{7AA4}\x{7AA5}\x{7AA6}\x{7AA7}\x{7AA8}\x{7AA9}\x{7AAA}\x{7AAB}' - . '\x{7AAC}\x{7AAD}\x{7AAE}\x{7AAF}\x{7AB0}\x{7AB1}\x{7AB2}\x{7AB3}\x{7AB4}' - . '\x{7AB5}\x{7AB6}\x{7AB7}\x{7AB8}\x{7ABA}\x{7ABE}\x{7ABF}\x{7AC0}\x{7AC1}' - . '\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}\x{7AC9}\x{7ACA}\x{7ACB}\x{7ACC}\x{7ACD}' - . '\x{7ACE}\x{7ACF}\x{7AD0}\x{7AD1}\x{7AD2}\x{7AD3}\x{7AD4}\x{7AD5}\x{7AD6}' - . '\x{7AD8}\x{7AD9}\x{7ADB}\x{7ADC}\x{7ADD}\x{7ADE}\x{7ADF}\x{7AE0}\x{7AE1}' - . '\x{7AE2}\x{7AE3}\x{7AE4}\x{7AE5}\x{7AE6}\x{7AE7}\x{7AE8}\x{7AEA}\x{7AEB}' - . '\x{7AEC}\x{7AED}\x{7AEE}\x{7AEF}\x{7AF0}\x{7AF1}\x{7AF2}\x{7AF3}\x{7AF4}' - . '\x{7AF6}\x{7AF7}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFB}\x{7AFD}\x{7AFE}\x{7AFF}' - . '\x{7B00}\x{7B01}\x{7B02}\x{7B03}\x{7B04}\x{7B05}\x{7B06}\x{7B08}\x{7B09}' - . '\x{7B0A}\x{7B0B}\x{7B0C}\x{7B0D}\x{7B0E}\x{7B0F}\x{7B10}\x{7B11}\x{7B12}' - . '\x{7B13}\x{7B14}\x{7B15}\x{7B16}\x{7B17}\x{7B18}\x{7B19}\x{7B1A}\x{7B1B}' - . '\x{7B1C}\x{7B1D}\x{7B1E}\x{7B20}\x{7B21}\x{7B22}\x{7B23}\x{7B24}\x{7B25}' - . '\x{7B26}\x{7B28}\x{7B2A}\x{7B2B}\x{7B2C}\x{7B2D}\x{7B2E}\x{7B2F}\x{7B30}' - . '\x{7B31}\x{7B32}\x{7B33}\x{7B34}\x{7B35}\x{7B36}\x{7B37}\x{7B38}\x{7B39}' - . '\x{7B3A}\x{7B3B}\x{7B3C}\x{7B3D}\x{7B3E}\x{7B3F}\x{7B40}\x{7B41}\x{7B43}' - . '\x{7B44}\x{7B45}\x{7B46}\x{7B47}\x{7B48}\x{7B49}\x{7B4A}\x{7B4B}\x{7B4C}' - . '\x{7B4D}\x{7B4E}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B55}\x{7B56}' - . '\x{7B57}\x{7B58}\x{7B59}\x{7B5A}\x{7B5B}\x{7B5C}\x{7B5D}\x{7B5E}\x{7B5F}' - . '\x{7B60}\x{7B61}\x{7B62}\x{7B63}\x{7B64}\x{7B65}\x{7B66}\x{7B67}\x{7B68}' - . '\x{7B69}\x{7B6A}\x{7B6B}\x{7B6C}\x{7B6D}\x{7B6E}\x{7B70}\x{7B71}\x{7B72}' - . '\x{7B73}\x{7B74}\x{7B75}\x{7B76}\x{7B77}\x{7B78}\x{7B79}\x{7B7B}\x{7B7C}' - . '\x{7B7D}\x{7B7E}\x{7B7F}\x{7B80}\x{7B81}\x{7B82}\x{7B83}\x{7B84}\x{7B85}' - . '\x{7B87}\x{7B88}\x{7B89}\x{7B8A}\x{7B8B}\x{7B8C}\x{7B8D}\x{7B8E}\x{7B8F}' - . '\x{7B90}\x{7B91}\x{7B93}\x{7B94}\x{7B95}\x{7B96}\x{7B97}\x{7B98}\x{7B99}' - . '\x{7B9A}\x{7B9B}\x{7B9C}\x{7B9D}\x{7B9E}\x{7B9F}\x{7BA0}\x{7BA1}\x{7BA2}' - . '\x{7BA4}\x{7BA6}\x{7BA7}\x{7BA8}\x{7BA9}\x{7BAA}\x{7BAB}\x{7BAC}\x{7BAD}' - . '\x{7BAE}\x{7BAF}\x{7BB1}\x{7BB3}\x{7BB4}\x{7BB5}\x{7BB6}\x{7BB7}\x{7BB8}' - . '\x{7BB9}\x{7BBA}\x{7BBB}\x{7BBC}\x{7BBD}\x{7BBE}\x{7BBF}\x{7BC0}\x{7BC1}' - . '\x{7BC2}\x{7BC3}\x{7BC4}\x{7BC5}\x{7BC6}\x{7BC7}\x{7BC8}\x{7BC9}\x{7BCA}' - . '\x{7BCB}\x{7BCC}\x{7BCD}\x{7BCE}\x{7BD0}\x{7BD1}\x{7BD2}\x{7BD3}\x{7BD4}' - . '\x{7BD5}\x{7BD6}\x{7BD7}\x{7BD8}\x{7BD9}\x{7BDA}\x{7BDB}\x{7BDC}\x{7BDD}' - . '\x{7BDE}\x{7BDF}\x{7BE0}\x{7BE1}\x{7BE2}\x{7BE3}\x{7BE4}\x{7BE5}\x{7BE6}' - . '\x{7BE7}\x{7BE8}\x{7BE9}\x{7BEA}\x{7BEB}\x{7BEC}\x{7BED}\x{7BEE}\x{7BEF}' - . '\x{7BF0}\x{7BF1}\x{7BF2}\x{7BF3}\x{7BF4}\x{7BF5}\x{7BF6}\x{7BF7}\x{7BF8}' - . '\x{7BF9}\x{7BFB}\x{7BFC}\x{7BFD}\x{7BFE}\x{7BFF}\x{7C00}\x{7C01}\x{7C02}' - . '\x{7C03}\x{7C04}\x{7C05}\x{7C06}\x{7C07}\x{7C08}\x{7C09}\x{7C0A}\x{7C0B}' - . '\x{7C0C}\x{7C0D}\x{7C0E}\x{7C0F}\x{7C10}\x{7C11}\x{7C12}\x{7C13}\x{7C15}' - . '\x{7C16}\x{7C17}\x{7C18}\x{7C19}\x{7C1A}\x{7C1C}\x{7C1D}\x{7C1E}\x{7C1F}' - . '\x{7C20}\x{7C21}\x{7C22}\x{7C23}\x{7C24}\x{7C25}\x{7C26}\x{7C27}\x{7C28}' - . '\x{7C29}\x{7C2A}\x{7C2B}\x{7C2C}\x{7C2D}\x{7C30}\x{7C31}\x{7C32}\x{7C33}' - . '\x{7C34}\x{7C35}\x{7C36}\x{7C37}\x{7C38}\x{7C39}\x{7C3A}\x{7C3B}\x{7C3C}' - . '\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C41}\x{7C42}\x{7C43}\x{7C44}\x{7C45}' - . '\x{7C46}\x{7C47}\x{7C48}\x{7C49}\x{7C4A}\x{7C4B}\x{7C4C}\x{7C4D}\x{7C4E}' - . '\x{7C50}\x{7C51}\x{7C53}\x{7C54}\x{7C56}\x{7C57}\x{7C58}\x{7C59}\x{7C5A}' - . '\x{7C5B}\x{7C5C}\x{7C5E}\x{7C5F}\x{7C60}\x{7C61}\x{7C62}\x{7C63}\x{7C64}' - . '\x{7C65}\x{7C66}\x{7C67}\x{7C68}\x{7C69}\x{7C6A}\x{7C6B}\x{7C6C}\x{7C6D}' - . '\x{7C6E}\x{7C6F}\x{7C70}\x{7C71}\x{7C72}\x{7C73}\x{7C74}\x{7C75}\x{7C77}' - . '\x{7C78}\x{7C79}\x{7C7A}\x{7C7B}\x{7C7C}\x{7C7D}\x{7C7E}\x{7C7F}\x{7C80}' - . '\x{7C81}\x{7C82}\x{7C84}\x{7C85}\x{7C86}\x{7C88}\x{7C89}\x{7C8A}\x{7C8B}' - . '\x{7C8C}\x{7C8D}\x{7C8E}\x{7C8F}\x{7C90}\x{7C91}\x{7C92}\x{7C94}\x{7C95}' - . '\x{7C96}\x{7C97}\x{7C98}\x{7C99}\x{7C9B}\x{7C9C}\x{7C9D}\x{7C9E}\x{7C9F}' - . '\x{7CA0}\x{7CA1}\x{7CA2}\x{7CA3}\x{7CA4}\x{7CA5}\x{7CA6}\x{7CA7}\x{7CA8}' - . '\x{7CA9}\x{7CAA}\x{7CAD}\x{7CAE}\x{7CAF}\x{7CB0}\x{7CB1}\x{7CB2}\x{7CB3}' - . '\x{7CB4}\x{7CB5}\x{7CB6}\x{7CB7}\x{7CB8}\x{7CB9}\x{7CBA}\x{7CBB}\x{7CBC}' - . '\x{7CBD}\x{7CBE}\x{7CBF}\x{7CC0}\x{7CC1}\x{7CC2}\x{7CC3}\x{7CC4}\x{7CC5}' - . '\x{7CC6}\x{7CC7}\x{7CC8}\x{7CC9}\x{7CCA}\x{7CCB}\x{7CCC}\x{7CCD}\x{7CCE}' - . '\x{7CCF}\x{7CD0}\x{7CD1}\x{7CD2}\x{7CD4}\x{7CD5}\x{7CD6}\x{7CD7}\x{7CD8}' - . '\x{7CD9}\x{7CDC}\x{7CDD}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE4}\x{7CE7}' - . '\x{7CE8}\x{7CE9}\x{7CEA}\x{7CEB}\x{7CEC}\x{7CED}\x{7CEE}\x{7CEF}\x{7CF0}' - . '\x{7CF1}\x{7CF2}\x{7CF3}\x{7CF4}\x{7CF5}\x{7CF6}\x{7CF7}\x{7CF8}\x{7CF9}' - . '\x{7CFA}\x{7CFB}\x{7CFD}\x{7CFE}\x{7D00}\x{7D01}\x{7D02}\x{7D03}\x{7D04}' - . '\x{7D05}\x{7D06}\x{7D07}\x{7D08}\x{7D09}\x{7D0A}\x{7D0B}\x{7D0C}\x{7D0D}' - . '\x{7D0E}\x{7D0F}\x{7D10}\x{7D11}\x{7D12}\x{7D13}\x{7D14}\x{7D15}\x{7D16}' - . '\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D1D}\x{7D1E}\x{7D1F}' - . '\x{7D20}\x{7D21}\x{7D22}\x{7D24}\x{7D25}\x{7D26}\x{7D27}\x{7D28}\x{7D29}' - . '\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D31}\x{7D32}\x{7D33}\x{7D34}' - . '\x{7D35}\x{7D36}\x{7D37}\x{7D38}\x{7D39}\x{7D3A}\x{7D3B}\x{7D3C}\x{7D3D}' - . '\x{7D3E}\x{7D3F}\x{7D40}\x{7D41}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}' - . '\x{7D47}\x{7D49}\x{7D4A}\x{7D4B}\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D51}' - . '\x{7D52}\x{7D53}\x{7D54}\x{7D55}\x{7D56}\x{7D57}\x{7D58}\x{7D59}\x{7D5B}' - . '\x{7D5C}\x{7D5D}\x{7D5E}\x{7D5F}\x{7D60}\x{7D61}\x{7D62}\x{7D63}\x{7D65}' - . '\x{7D66}\x{7D67}\x{7D68}\x{7D69}\x{7D6A}\x{7D6B}\x{7D6C}\x{7D6D}\x{7D6E}' - . '\x{7D6F}\x{7D70}\x{7D71}\x{7D72}\x{7D73}\x{7D74}\x{7D75}\x{7D76}\x{7D77}' - . '\x{7D79}\x{7D7A}\x{7D7B}\x{7D7C}\x{7D7D}\x{7D7E}\x{7D7F}\x{7D80}\x{7D81}' - . '\x{7D83}\x{7D84}\x{7D85}\x{7D86}\x{7D87}\x{7D88}\x{7D89}\x{7D8A}\x{7D8B}' - . '\x{7D8C}\x{7D8D}\x{7D8E}\x{7D8F}\x{7D90}\x{7D91}\x{7D92}\x{7D93}\x{7D94}' - . '\x{7D96}\x{7D97}\x{7D99}\x{7D9B}\x{7D9C}\x{7D9D}\x{7D9E}\x{7D9F}\x{7DA0}' - . '\x{7DA1}\x{7DA2}\x{7DA3}\x{7DA5}\x{7DA6}\x{7DA7}\x{7DA9}\x{7DAA}\x{7DAB}' - . '\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}\x{7DB1}\x{7DB2}\x{7DB3}\x{7DB4}' - . '\x{7DB5}\x{7DB6}\x{7DB7}\x{7DB8}\x{7DB9}\x{7DBA}\x{7DBB}\x{7DBC}\x{7DBD}' - . '\x{7DBE}\x{7DBF}\x{7DC0}\x{7DC1}\x{7DC2}\x{7DC3}\x{7DC4}\x{7DC5}\x{7DC6}' - . '\x{7DC7}\x{7DC8}\x{7DC9}\x{7DCA}\x{7DCB}\x{7DCC}\x{7DCE}\x{7DCF}\x{7DD0}' - . '\x{7DD1}\x{7DD2}\x{7DD4}\x{7DD5}\x{7DD6}\x{7DD7}\x{7DD8}\x{7DD9}\x{7DDA}' - . '\x{7DDB}\x{7DDD}\x{7DDE}\x{7DDF}\x{7DE0}\x{7DE1}\x{7DE2}\x{7DE3}\x{7DE6}' - . '\x{7DE7}\x{7DE8}\x{7DE9}\x{7DEA}\x{7DEC}\x{7DED}\x{7DEE}\x{7DEF}\x{7DF0}' - . '\x{7DF1}\x{7DF2}\x{7DF3}\x{7DF4}\x{7DF5}\x{7DF6}\x{7DF7}\x{7DF8}\x{7DF9}' - . '\x{7DFA}\x{7DFB}\x{7DFC}\x{7E00}\x{7E01}\x{7E02}\x{7E03}\x{7E04}\x{7E05}' - . '\x{7E06}\x{7E07}\x{7E08}\x{7E09}\x{7E0A}\x{7E0B}\x{7E0C}\x{7E0D}\x{7E0E}' - . '\x{7E0F}\x{7E10}\x{7E11}\x{7E12}\x{7E13}\x{7E14}\x{7E15}\x{7E16}\x{7E17}' - . '\x{7E19}\x{7E1A}\x{7E1B}\x{7E1C}\x{7E1D}\x{7E1E}\x{7E1F}\x{7E20}\x{7E21}' - . '\x{7E22}\x{7E23}\x{7E24}\x{7E25}\x{7E26}\x{7E27}\x{7E28}\x{7E29}\x{7E2A}' - . '\x{7E2B}\x{7E2C}\x{7E2D}\x{7E2E}\x{7E2F}\x{7E30}\x{7E31}\x{7E32}\x{7E33}' - . '\x{7E34}\x{7E35}\x{7E36}\x{7E37}\x{7E38}\x{7E39}\x{7E3A}\x{7E3B}\x{7E3C}' - . '\x{7E3D}\x{7E3E}\x{7E3F}\x{7E40}\x{7E41}\x{7E42}\x{7E43}\x{7E44}\x{7E45}' - . '\x{7E46}\x{7E47}\x{7E48}\x{7E49}\x{7E4C}\x{7E4D}\x{7E4E}\x{7E4F}\x{7E50}' - . '\x{7E51}\x{7E52}\x{7E53}\x{7E54}\x{7E55}\x{7E56}\x{7E57}\x{7E58}\x{7E59}' - . '\x{7E5A}\x{7E5C}\x{7E5D}\x{7E5E}\x{7E5F}\x{7E60}\x{7E61}\x{7E62}\x{7E63}' - . '\x{7E65}\x{7E66}\x{7E67}\x{7E68}\x{7E69}\x{7E6A}\x{7E6B}\x{7E6C}\x{7E6D}' - . '\x{7E6E}\x{7E6F}\x{7E70}\x{7E71}\x{7E72}\x{7E73}\x{7E74}\x{7E75}\x{7E76}' - . '\x{7E77}\x{7E78}\x{7E79}\x{7E7A}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7E}\x{7E7F}' - . '\x{7E80}\x{7E81}\x{7E82}\x{7E83}\x{7E84}\x{7E85}\x{7E86}\x{7E87}\x{7E88}' - . '\x{7E89}\x{7E8A}\x{7E8B}\x{7E8C}\x{7E8D}\x{7E8E}\x{7E8F}\x{7E90}\x{7E91}' - . '\x{7E92}\x{7E93}\x{7E94}\x{7E95}\x{7E96}\x{7E97}\x{7E98}\x{7E99}\x{7E9A}' - . '\x{7E9B}\x{7E9C}\x{7E9E}\x{7E9F}\x{7EA0}\x{7EA1}\x{7EA2}\x{7EA3}\x{7EA4}' - . '\x{7EA5}\x{7EA6}\x{7EA7}\x{7EA8}\x{7EA9}\x{7EAA}\x{7EAB}\x{7EAC}\x{7EAD}' - . '\x{7EAE}\x{7EAF}\x{7EB0}\x{7EB1}\x{7EB2}\x{7EB3}\x{7EB4}\x{7EB5}\x{7EB6}' - . '\x{7EB7}\x{7EB8}\x{7EB9}\x{7EBA}\x{7EBB}\x{7EBC}\x{7EBD}\x{7EBE}\x{7EBF}' - . '\x{7EC0}\x{7EC1}\x{7EC2}\x{7EC3}\x{7EC4}\x{7EC5}\x{7EC6}\x{7EC7}\x{7EC8}' - . '\x{7EC9}\x{7ECA}\x{7ECB}\x{7ECC}\x{7ECD}\x{7ECE}\x{7ECF}\x{7ED0}\x{7ED1}' - . '\x{7ED2}\x{7ED3}\x{7ED4}\x{7ED5}\x{7ED6}\x{7ED7}\x{7ED8}\x{7ED9}\x{7EDA}' - . '\x{7EDB}\x{7EDC}\x{7EDD}\x{7EDE}\x{7EDF}\x{7EE0}\x{7EE1}\x{7EE2}\x{7EE3}' - . '\x{7EE4}\x{7EE5}\x{7EE6}\x{7EE7}\x{7EE8}\x{7EE9}\x{7EEA}\x{7EEB}\x{7EEC}' - . '\x{7EED}\x{7EEE}\x{7EEF}\x{7EF0}\x{7EF1}\x{7EF2}\x{7EF3}\x{7EF4}\x{7EF5}' - . '\x{7EF6}\x{7EF7}\x{7EF8}\x{7EF9}\x{7EFA}\x{7EFB}\x{7EFC}\x{7EFD}\x{7EFE}' - . '\x{7EFF}\x{7F00}\x{7F01}\x{7F02}\x{7F03}\x{7F04}\x{7F05}\x{7F06}\x{7F07}' - . '\x{7F08}\x{7F09}\x{7F0A}\x{7F0B}\x{7F0C}\x{7F0D}\x{7F0E}\x{7F0F}\x{7F10}' - . '\x{7F11}\x{7F12}\x{7F13}\x{7F14}\x{7F15}\x{7F16}\x{7F17}\x{7F18}\x{7F19}' - . '\x{7F1A}\x{7F1B}\x{7F1C}\x{7F1D}\x{7F1E}\x{7F1F}\x{7F20}\x{7F21}\x{7F22}' - . '\x{7F23}\x{7F24}\x{7F25}\x{7F26}\x{7F27}\x{7F28}\x{7F29}\x{7F2A}\x{7F2B}' - . '\x{7F2C}\x{7F2D}\x{7F2E}\x{7F2F}\x{7F30}\x{7F31}\x{7F32}\x{7F33}\x{7F34}' - . '\x{7F35}\x{7F36}\x{7F37}\x{7F38}\x{7F39}\x{7F3A}\x{7F3D}\x{7F3E}\x{7F3F}' - . '\x{7F40}\x{7F42}\x{7F43}\x{7F44}\x{7F45}\x{7F47}\x{7F48}\x{7F49}\x{7F4A}' - . '\x{7F4B}\x{7F4C}\x{7F4D}\x{7F4E}\x{7F4F}\x{7F50}\x{7F51}\x{7F52}\x{7F53}' - . '\x{7F54}\x{7F55}\x{7F56}\x{7F57}\x{7F58}\x{7F5A}\x{7F5B}\x{7F5C}\x{7F5D}' - . '\x{7F5E}\x{7F5F}\x{7F60}\x{7F61}\x{7F62}\x{7F63}\x{7F64}\x{7F65}\x{7F66}' - . '\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6C}\x{7F6D}\x{7F6E}\x{7F6F}' - . '\x{7F70}\x{7F71}\x{7F72}\x{7F73}\x{7F74}\x{7F75}\x{7F76}\x{7F77}\x{7F78}' - . '\x{7F79}\x{7F7A}\x{7F7B}\x{7F7C}\x{7F7D}\x{7F7E}\x{7F7F}\x{7F80}\x{7F81}' - . '\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}\x{7F88}\x{7F89}\x{7F8A}\x{7F8B}' - . '\x{7F8C}\x{7F8D}\x{7F8E}\x{7F8F}\x{7F91}\x{7F92}\x{7F93}\x{7F94}\x{7F95}' - . '\x{7F96}\x{7F98}\x{7F9A}\x{7F9B}\x{7F9C}\x{7F9D}\x{7F9E}\x{7F9F}\x{7FA0}' - . '\x{7FA1}\x{7FA2}\x{7FA3}\x{7FA4}\x{7FA5}\x{7FA6}\x{7FA7}\x{7FA8}\x{7FA9}' - . '\x{7FAA}\x{7FAB}\x{7FAC}\x{7FAD}\x{7FAE}\x{7FAF}\x{7FB0}\x{7FB1}\x{7FB2}' - . '\x{7FB3}\x{7FB5}\x{7FB6}\x{7FB7}\x{7FB8}\x{7FB9}\x{7FBA}\x{7FBB}\x{7FBC}' - . '\x{7FBD}\x{7FBE}\x{7FBF}\x{7FC0}\x{7FC1}\x{7FC2}\x{7FC3}\x{7FC4}\x{7FC5}' - . '\x{7FC6}\x{7FC7}\x{7FC8}\x{7FC9}\x{7FCA}\x{7FCB}\x{7FCC}\x{7FCD}\x{7FCE}' - . '\x{7FCF}\x{7FD0}\x{7FD1}\x{7FD2}\x{7FD3}\x{7FD4}\x{7FD5}\x{7FD7}\x{7FD8}' - . '\x{7FD9}\x{7FDA}\x{7FDB}\x{7FDC}\x{7FDE}\x{7FDF}\x{7FE0}\x{7FE1}\x{7FE2}' - . '\x{7FE3}\x{7FE5}\x{7FE6}\x{7FE7}\x{7FE8}\x{7FE9}\x{7FEA}\x{7FEB}\x{7FEC}' - . '\x{7FED}\x{7FEE}\x{7FEF}\x{7FF0}\x{7FF1}\x{7FF2}\x{7FF3}\x{7FF4}\x{7FF5}' - . '\x{7FF6}\x{7FF7}\x{7FF8}\x{7FF9}\x{7FFA}\x{7FFB}\x{7FFC}\x{7FFD}\x{7FFE}' - . '\x{7FFF}\x{8000}\x{8001}\x{8002}\x{8003}\x{8004}\x{8005}\x{8006}\x{8007}' - . '\x{8008}\x{8009}\x{800B}\x{800C}\x{800D}\x{800E}\x{800F}\x{8010}\x{8011}' - . '\x{8012}\x{8013}\x{8014}\x{8015}\x{8016}\x{8017}\x{8018}\x{8019}\x{801A}' - . '\x{801B}\x{801C}\x{801D}\x{801E}\x{801F}\x{8020}\x{8021}\x{8022}\x{8023}' - . '\x{8024}\x{8025}\x{8026}\x{8027}\x{8028}\x{8029}\x{802A}\x{802B}\x{802C}' - . '\x{802D}\x{802E}\x{8030}\x{8031}\x{8032}\x{8033}\x{8034}\x{8035}\x{8036}' - . '\x{8037}\x{8038}\x{8039}\x{803A}\x{803B}\x{803D}\x{803E}\x{803F}\x{8041}' - . '\x{8042}\x{8043}\x{8044}\x{8045}\x{8046}\x{8047}\x{8048}\x{8049}\x{804A}' - . '\x{804B}\x{804C}\x{804D}\x{804E}\x{804F}\x{8050}\x{8051}\x{8052}\x{8053}' - . '\x{8054}\x{8055}\x{8056}\x{8057}\x{8058}\x{8059}\x{805A}\x{805B}\x{805C}' - . '\x{805D}\x{805E}\x{805F}\x{8060}\x{8061}\x{8062}\x{8063}\x{8064}\x{8065}' - . '\x{8067}\x{8068}\x{8069}\x{806A}\x{806B}\x{806C}\x{806D}\x{806E}\x{806F}' - . '\x{8070}\x{8071}\x{8072}\x{8073}\x{8074}\x{8075}\x{8076}\x{8077}\x{8078}' - . '\x{8079}\x{807A}\x{807B}\x{807C}\x{807D}\x{807E}\x{807F}\x{8080}\x{8081}' - . '\x{8082}\x{8083}\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808A}\x{808B}' - . '\x{808C}\x{808D}\x{808F}\x{8090}\x{8091}\x{8092}\x{8093}\x{8095}\x{8096}' - . '\x{8097}\x{8098}\x{8099}\x{809A}\x{809B}\x{809C}\x{809D}\x{809E}\x{809F}' - . '\x{80A0}\x{80A1}\x{80A2}\x{80A3}\x{80A4}\x{80A5}\x{80A9}\x{80AA}\x{80AB}' - . '\x{80AD}\x{80AE}\x{80AF}\x{80B0}\x{80B1}\x{80B2}\x{80B4}\x{80B5}\x{80B6}' - . '\x{80B7}\x{80B8}\x{80BA}\x{80BB}\x{80BC}\x{80BD}\x{80BE}\x{80BF}\x{80C0}' - . '\x{80C1}\x{80C2}\x{80C3}\x{80C4}\x{80C5}\x{80C6}\x{80C7}\x{80C8}\x{80C9}' - . '\x{80CA}\x{80CB}\x{80CC}\x{80CD}\x{80CE}\x{80CF}\x{80D0}\x{80D1}\x{80D2}' - . '\x{80D3}\x{80D4}\x{80D5}\x{80D6}\x{80D7}\x{80D8}\x{80D9}\x{80DA}\x{80DB}' - . '\x{80DC}\x{80DD}\x{80DE}\x{80E0}\x{80E1}\x{80E2}\x{80E3}\x{80E4}\x{80E5}' - . '\x{80E6}\x{80E7}\x{80E8}\x{80E9}\x{80EA}\x{80EB}\x{80EC}\x{80ED}\x{80EE}' - . '\x{80EF}\x{80F0}\x{80F1}\x{80F2}\x{80F3}\x{80F4}\x{80F5}\x{80F6}\x{80F7}' - . '\x{80F8}\x{80F9}\x{80FA}\x{80FB}\x{80FC}\x{80FD}\x{80FE}\x{80FF}\x{8100}' - . '\x{8101}\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{810B}' - . '\x{810C}\x{810D}\x{810E}\x{810F}\x{8110}\x{8111}\x{8112}\x{8113}\x{8114}' - . '\x{8115}\x{8116}\x{8118}\x{8119}\x{811A}\x{811B}\x{811C}\x{811D}\x{811E}' - . '\x{811F}\x{8120}\x{8121}\x{8122}\x{8123}\x{8124}\x{8125}\x{8126}\x{8127}' - . '\x{8128}\x{8129}\x{812A}\x{812B}\x{812C}\x{812D}\x{812E}\x{812F}\x{8130}' - . '\x{8131}\x{8132}\x{8136}\x{8137}\x{8138}\x{8139}\x{813A}\x{813B}\x{813C}' - . '\x{813D}\x{813E}\x{813F}\x{8140}\x{8141}\x{8142}\x{8143}\x{8144}\x{8145}' - . '\x{8146}\x{8147}\x{8148}\x{8149}\x{814A}\x{814B}\x{814C}\x{814D}\x{814E}' - . '\x{814F}\x{8150}\x{8151}\x{8152}\x{8153}\x{8154}\x{8155}\x{8156}\x{8157}' - . '\x{8158}\x{8159}\x{815A}\x{815B}\x{815C}\x{815D}\x{815E}\x{8160}\x{8161}' - . '\x{8162}\x{8163}\x{8164}\x{8165}\x{8166}\x{8167}\x{8168}\x{8169}\x{816A}' - . '\x{816B}\x{816C}\x{816D}\x{816E}\x{816F}\x{8170}\x{8171}\x{8172}\x{8173}' - . '\x{8174}\x{8175}\x{8176}\x{8177}\x{8178}\x{8179}\x{817A}\x{817B}\x{817C}' - . '\x{817D}\x{817E}\x{817F}\x{8180}\x{8181}\x{8182}\x{8183}\x{8185}\x{8186}' - . '\x{8187}\x{8188}\x{8189}\x{818A}\x{818B}\x{818C}\x{818D}\x{818E}\x{818F}' - . '\x{8191}\x{8192}\x{8193}\x{8194}\x{8195}\x{8197}\x{8198}\x{8199}\x{819A}' - . '\x{819B}\x{819C}\x{819D}\x{819E}\x{819F}\x{81A0}\x{81A1}\x{81A2}\x{81A3}' - . '\x{81A4}\x{81A5}\x{81A6}\x{81A7}\x{81A8}\x{81A9}\x{81AA}\x{81AB}\x{81AC}' - . '\x{81AD}\x{81AE}\x{81AF}\x{81B0}\x{81B1}\x{81B2}\x{81B3}\x{81B4}\x{81B5}' - . '\x{81B6}\x{81B7}\x{81B8}\x{81B9}\x{81BA}\x{81BB}\x{81BC}\x{81BD}\x{81BE}' - . '\x{81BF}\x{81C0}\x{81C1}\x{81C2}\x{81C3}\x{81C4}\x{81C5}\x{81C6}\x{81C7}' - . '\x{81C8}\x{81C9}\x{81CA}\x{81CC}\x{81CD}\x{81CE}\x{81CF}\x{81D0}\x{81D1}' - . '\x{81D2}\x{81D4}\x{81D5}\x{81D6}\x{81D7}\x{81D8}\x{81D9}\x{81DA}\x{81DB}' - . '\x{81DC}\x{81DD}\x{81DE}\x{81DF}\x{81E0}\x{81E1}\x{81E2}\x{81E3}\x{81E5}' - . '\x{81E6}\x{81E7}\x{81E8}\x{81E9}\x{81EA}\x{81EB}\x{81EC}\x{81ED}\x{81EE}' - . '\x{81F1}\x{81F2}\x{81F3}\x{81F4}\x{81F5}\x{81F6}\x{81F7}\x{81F8}\x{81F9}' - . '\x{81FA}\x{81FB}\x{81FC}\x{81FD}\x{81FE}\x{81FF}\x{8200}\x{8201}\x{8202}' - . '\x{8203}\x{8204}\x{8205}\x{8206}\x{8207}\x{8208}\x{8209}\x{820A}\x{820B}' - . '\x{820C}\x{820D}\x{820E}\x{820F}\x{8210}\x{8211}\x{8212}\x{8214}\x{8215}' - . '\x{8216}\x{8218}\x{8219}\x{821A}\x{821B}\x{821C}\x{821D}\x{821E}\x{821F}' - . '\x{8220}\x{8221}\x{8222}\x{8223}\x{8225}\x{8226}\x{8227}\x{8228}\x{8229}' - . '\x{822A}\x{822B}\x{822C}\x{822D}\x{822F}\x{8230}\x{8231}\x{8232}\x{8233}' - . '\x{8234}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{823A}\x{823B}\x{823C}' - . '\x{823D}\x{823E}\x{823F}\x{8240}\x{8242}\x{8243}\x{8244}\x{8245}\x{8246}' - . '\x{8247}\x{8248}\x{8249}\x{824A}\x{824B}\x{824C}\x{824D}\x{824E}\x{824F}' - . '\x{8250}\x{8251}\x{8252}\x{8253}\x{8254}\x{8255}\x{8256}\x{8257}\x{8258}' - . '\x{8259}\x{825A}\x{825B}\x{825C}\x{825D}\x{825E}\x{825F}\x{8260}\x{8261}' - . '\x{8263}\x{8264}\x{8266}\x{8267}\x{8268}\x{8269}\x{826A}\x{826B}\x{826C}' - . '\x{826D}\x{826E}\x{826F}\x{8270}\x{8271}\x{8272}\x{8273}\x{8274}\x{8275}' - . '\x{8276}\x{8277}\x{8278}\x{8279}\x{827A}\x{827B}\x{827C}\x{827D}\x{827E}' - . '\x{827F}\x{8280}\x{8281}\x{8282}\x{8283}\x{8284}\x{8285}\x{8286}\x{8287}' - . '\x{8288}\x{8289}\x{828A}\x{828B}\x{828D}\x{828E}\x{828F}\x{8290}\x{8291}' - . '\x{8292}\x{8293}\x{8294}\x{8295}\x{8296}\x{8297}\x{8298}\x{8299}\x{829A}' - . '\x{829B}\x{829C}\x{829D}\x{829E}\x{829F}\x{82A0}\x{82A1}\x{82A2}\x{82A3}' - . '\x{82A4}\x{82A5}\x{82A6}\x{82A7}\x{82A8}\x{82A9}\x{82AA}\x{82AB}\x{82AC}' - . '\x{82AD}\x{82AE}\x{82AF}\x{82B0}\x{82B1}\x{82B3}\x{82B4}\x{82B5}\x{82B6}' - . '\x{82B7}\x{82B8}\x{82B9}\x{82BA}\x{82BB}\x{82BC}\x{82BD}\x{82BE}\x{82BF}' - . '\x{82C0}\x{82C1}\x{82C2}\x{82C3}\x{82C4}\x{82C5}\x{82C6}\x{82C7}\x{82C8}' - . '\x{82C9}\x{82CA}\x{82CB}\x{82CC}\x{82CD}\x{82CE}\x{82CF}\x{82D0}\x{82D1}' - . '\x{82D2}\x{82D3}\x{82D4}\x{82D5}\x{82D6}\x{82D7}\x{82D8}\x{82D9}\x{82DA}' - . '\x{82DB}\x{82DC}\x{82DD}\x{82DE}\x{82DF}\x{82E0}\x{82E1}\x{82E3}\x{82E4}' - . '\x{82E5}\x{82E6}\x{82E7}\x{82E8}\x{82E9}\x{82EA}\x{82EB}\x{82EC}\x{82ED}' - . '\x{82EE}\x{82EF}\x{82F0}\x{82F1}\x{82F2}\x{82F3}\x{82F4}\x{82F5}\x{82F6}' - . '\x{82F7}\x{82F8}\x{82F9}\x{82FA}\x{82FB}\x{82FD}\x{82FE}\x{82FF}\x{8300}' - . '\x{8301}\x{8302}\x{8303}\x{8304}\x{8305}\x{8306}\x{8307}\x{8308}\x{8309}' - . '\x{830B}\x{830C}\x{830D}\x{830E}\x{830F}\x{8311}\x{8312}\x{8313}\x{8314}' - . '\x{8315}\x{8316}\x{8317}\x{8318}\x{8319}\x{831A}\x{831B}\x{831C}\x{831D}' - . '\x{831E}\x{831F}\x{8320}\x{8321}\x{8322}\x{8323}\x{8324}\x{8325}\x{8326}' - . '\x{8327}\x{8328}\x{8329}\x{832A}\x{832B}\x{832C}\x{832D}\x{832E}\x{832F}' - . '\x{8331}\x{8332}\x{8333}\x{8334}\x{8335}\x{8336}\x{8337}\x{8338}\x{8339}' - . '\x{833A}\x{833B}\x{833C}\x{833D}\x{833E}\x{833F}\x{8340}\x{8341}\x{8342}' - . '\x{8343}\x{8344}\x{8345}\x{8346}\x{8347}\x{8348}\x{8349}\x{834A}\x{834B}' - . '\x{834C}\x{834D}\x{834E}\x{834F}\x{8350}\x{8351}\x{8352}\x{8353}\x{8354}' - . '\x{8356}\x{8357}\x{8358}\x{8359}\x{835A}\x{835B}\x{835C}\x{835D}\x{835E}' - . '\x{835F}\x{8360}\x{8361}\x{8362}\x{8363}\x{8364}\x{8365}\x{8366}\x{8367}' - . '\x{8368}\x{8369}\x{836A}\x{836B}\x{836C}\x{836D}\x{836E}\x{836F}\x{8370}' - . '\x{8371}\x{8372}\x{8373}\x{8374}\x{8375}\x{8376}\x{8377}\x{8378}\x{8379}' - . '\x{837A}\x{837B}\x{837C}\x{837D}\x{837E}\x{837F}\x{8380}\x{8381}\x{8382}' - . '\x{8383}\x{8384}\x{8385}\x{8386}\x{8387}\x{8388}\x{8389}\x{838A}\x{838B}' - . '\x{838C}\x{838D}\x{838E}\x{838F}\x{8390}\x{8391}\x{8392}\x{8393}\x{8394}' - . '\x{8395}\x{8396}\x{8397}\x{8398}\x{8399}\x{839A}\x{839B}\x{839C}\x{839D}' - . '\x{839E}\x{83A0}\x{83A1}\x{83A2}\x{83A3}\x{83A4}\x{83A5}\x{83A6}\x{83A7}' - . '\x{83A8}\x{83A9}\x{83AA}\x{83AB}\x{83AC}\x{83AD}\x{83AE}\x{83AF}\x{83B0}' - . '\x{83B1}\x{83B2}\x{83B3}\x{83B4}\x{83B6}\x{83B7}\x{83B8}\x{83B9}\x{83BA}' - . '\x{83BB}\x{83BC}\x{83BD}\x{83BF}\x{83C0}\x{83C1}\x{83C2}\x{83C3}\x{83C4}' - . '\x{83C5}\x{83C6}\x{83C7}\x{83C8}\x{83C9}\x{83CA}\x{83CB}\x{83CC}\x{83CD}' - . '\x{83CE}\x{83CF}\x{83D0}\x{83D1}\x{83D2}\x{83D3}\x{83D4}\x{83D5}\x{83D6}' - . '\x{83D7}\x{83D8}\x{83D9}\x{83DA}\x{83DB}\x{83DC}\x{83DD}\x{83DE}\x{83DF}' - . '\x{83E0}\x{83E1}\x{83E2}\x{83E3}\x{83E4}\x{83E5}\x{83E7}\x{83E8}\x{83E9}' - . '\x{83EA}\x{83EB}\x{83EC}\x{83EE}\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F3}' - . '\x{83F4}\x{83F5}\x{83F6}\x{83F7}\x{83F8}\x{83F9}\x{83FA}\x{83FB}\x{83FC}' - . '\x{83FD}\x{83FE}\x{83FF}\x{8400}\x{8401}\x{8402}\x{8403}\x{8404}\x{8405}' - . '\x{8406}\x{8407}\x{8408}\x{8409}\x{840A}\x{840B}\x{840C}\x{840D}\x{840E}' - . '\x{840F}\x{8410}\x{8411}\x{8412}\x{8413}\x{8415}\x{8418}\x{8419}\x{841A}' - . '\x{841B}\x{841C}\x{841D}\x{841E}\x{8421}\x{8422}\x{8423}\x{8424}\x{8425}' - . '\x{8426}\x{8427}\x{8428}\x{8429}\x{842A}\x{842B}\x{842C}\x{842D}\x{842E}' - . '\x{842F}\x{8430}\x{8431}\x{8432}\x{8433}\x{8434}\x{8435}\x{8436}\x{8437}' - . '\x{8438}\x{8439}\x{843A}\x{843B}\x{843C}\x{843D}\x{843E}\x{843F}\x{8440}' - . '\x{8441}\x{8442}\x{8443}\x{8444}\x{8445}\x{8446}\x{8447}\x{8448}\x{8449}' - . '\x{844A}\x{844B}\x{844C}\x{844D}\x{844E}\x{844F}\x{8450}\x{8451}\x{8452}' - . '\x{8453}\x{8454}\x{8455}\x{8456}\x{8457}\x{8459}\x{845A}\x{845B}\x{845C}' - . '\x{845D}\x{845E}\x{845F}\x{8460}\x{8461}\x{8462}\x{8463}\x{8464}\x{8465}' - . '\x{8466}\x{8467}\x{8468}\x{8469}\x{846A}\x{846B}\x{846C}\x{846D}\x{846E}' - . '\x{846F}\x{8470}\x{8471}\x{8472}\x{8473}\x{8474}\x{8475}\x{8476}\x{8477}' - . '\x{8478}\x{8479}\x{847A}\x{847B}\x{847C}\x{847D}\x{847E}\x{847F}\x{8480}' - . '\x{8481}\x{8482}\x{8484}\x{8485}\x{8486}\x{8487}\x{8488}\x{8489}\x{848A}' - . '\x{848B}\x{848C}\x{848D}\x{848E}\x{848F}\x{8490}\x{8491}\x{8492}\x{8493}' - . '\x{8494}\x{8496}\x{8497}\x{8498}\x{8499}\x{849A}\x{849B}\x{849C}\x{849D}' - . '\x{849E}\x{849F}\x{84A0}\x{84A1}\x{84A2}\x{84A3}\x{84A4}\x{84A5}\x{84A6}' - . '\x{84A7}\x{84A8}\x{84A9}\x{84AA}\x{84AB}\x{84AC}\x{84AE}\x{84AF}\x{84B0}' - . '\x{84B1}\x{84B2}\x{84B3}\x{84B4}\x{84B5}\x{84B6}\x{84B8}\x{84B9}\x{84BA}' - . '\x{84BB}\x{84BC}\x{84BD}\x{84BE}\x{84BF}\x{84C0}\x{84C1}\x{84C2}\x{84C4}' - . '\x{84C5}\x{84C6}\x{84C7}\x{84C8}\x{84C9}\x{84CA}\x{84CB}\x{84CC}\x{84CD}' - . '\x{84CE}\x{84CF}\x{84D0}\x{84D1}\x{84D2}\x{84D3}\x{84D4}\x{84D5}\x{84D6}' - . '\x{84D7}\x{84D8}\x{84D9}\x{84DB}\x{84DC}\x{84DD}\x{84DE}\x{84DF}\x{84E0}' - . '\x{84E1}\x{84E2}\x{84E3}\x{84E4}\x{84E5}\x{84E6}\x{84E7}\x{84E8}\x{84E9}' - . '\x{84EA}\x{84EB}\x{84EC}\x{84EE}\x{84EF}\x{84F0}\x{84F1}\x{84F2}\x{84F3}' - . '\x{84F4}\x{84F5}\x{84F6}\x{84F7}\x{84F8}\x{84F9}\x{84FA}\x{84FB}\x{84FC}' - . '\x{84FD}\x{84FE}\x{84FF}\x{8500}\x{8501}\x{8502}\x{8503}\x{8504}\x{8506}' - . '\x{8507}\x{8508}\x{8509}\x{850A}\x{850B}\x{850C}\x{850D}\x{850E}\x{850F}' - . '\x{8511}\x{8512}\x{8513}\x{8514}\x{8515}\x{8516}\x{8517}\x{8518}\x{8519}' - . '\x{851A}\x{851B}\x{851C}\x{851D}\x{851E}\x{851F}\x{8520}\x{8521}\x{8522}' - . '\x{8523}\x{8524}\x{8525}\x{8526}\x{8527}\x{8528}\x{8529}\x{852A}\x{852B}' - . '\x{852C}\x{852D}\x{852E}\x{852F}\x{8530}\x{8531}\x{8534}\x{8535}\x{8536}' - . '\x{8537}\x{8538}\x{8539}\x{853A}\x{853B}\x{853C}\x{853D}\x{853E}\x{853F}' - . '\x{8540}\x{8541}\x{8542}\x{8543}\x{8544}\x{8545}\x{8546}\x{8547}\x{8548}' - . '\x{8549}\x{854A}\x{854B}\x{854D}\x{854E}\x{854F}\x{8551}\x{8552}\x{8553}' - . '\x{8554}\x{8555}\x{8556}\x{8557}\x{8558}\x{8559}\x{855A}\x{855B}\x{855C}' - . '\x{855D}\x{855E}\x{855F}\x{8560}\x{8561}\x{8562}\x{8563}\x{8564}\x{8565}' - . '\x{8566}\x{8567}\x{8568}\x{8569}\x{856A}\x{856B}\x{856C}\x{856D}\x{856E}' - . '\x{856F}\x{8570}\x{8571}\x{8572}\x{8573}\x{8574}\x{8575}\x{8576}\x{8577}' - . '\x{8578}\x{8579}\x{857A}\x{857B}\x{857C}\x{857D}\x{857E}\x{8580}\x{8581}' - . '\x{8582}\x{8583}\x{8584}\x{8585}\x{8586}\x{8587}\x{8588}\x{8589}\x{858A}' - . '\x{858B}\x{858C}\x{858D}\x{858E}\x{858F}\x{8590}\x{8591}\x{8592}\x{8594}' - . '\x{8595}\x{8596}\x{8598}\x{8599}\x{859A}\x{859B}\x{859C}\x{859D}\x{859E}' - . '\x{859F}\x{85A0}\x{85A1}\x{85A2}\x{85A3}\x{85A4}\x{85A5}\x{85A6}\x{85A7}' - . '\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AD}\x{85AE}\x{85AF}\x{85B0}' - . '\x{85B1}\x{85B3}\x{85B4}\x{85B5}\x{85B6}\x{85B7}\x{85B8}\x{85B9}\x{85BA}' - . '\x{85BC}\x{85BD}\x{85BE}\x{85BF}\x{85C0}\x{85C1}\x{85C2}\x{85C3}\x{85C4}' - . '\x{85C5}\x{85C6}\x{85C7}\x{85C8}\x{85C9}\x{85CA}\x{85CB}\x{85CD}\x{85CE}' - . '\x{85CF}\x{85D0}\x{85D1}\x{85D2}\x{85D3}\x{85D4}\x{85D5}\x{85D6}\x{85D7}' - . '\x{85D8}\x{85D9}\x{85DA}\x{85DB}\x{85DC}\x{85DD}\x{85DE}\x{85DF}\x{85E0}' - . '\x{85E1}\x{85E2}\x{85E3}\x{85E4}\x{85E5}\x{85E6}\x{85E7}\x{85E8}\x{85E9}' - . '\x{85EA}\x{85EB}\x{85EC}\x{85ED}\x{85EF}\x{85F0}\x{85F1}\x{85F2}\x{85F4}' - . '\x{85F5}\x{85F6}\x{85F7}\x{85F8}\x{85F9}\x{85FA}\x{85FB}\x{85FD}\x{85FE}' - . '\x{85FF}\x{8600}\x{8601}\x{8602}\x{8604}\x{8605}\x{8606}\x{8607}\x{8608}' - . '\x{8609}\x{860A}\x{860B}\x{860C}\x{860F}\x{8611}\x{8612}\x{8613}\x{8614}' - . '\x{8616}\x{8617}\x{8618}\x{8619}\x{861A}\x{861B}\x{861C}\x{861E}\x{861F}' - . '\x{8620}\x{8621}\x{8622}\x{8623}\x{8624}\x{8625}\x{8626}\x{8627}\x{8628}' - . '\x{8629}\x{862A}\x{862B}\x{862C}\x{862D}\x{862E}\x{862F}\x{8630}\x{8631}' - . '\x{8632}\x{8633}\x{8634}\x{8635}\x{8636}\x{8638}\x{8639}\x{863A}\x{863B}' - . '\x{863C}\x{863D}\x{863E}\x{863F}\x{8640}\x{8641}\x{8642}\x{8643}\x{8644}' - . '\x{8645}\x{8646}\x{8647}\x{8648}\x{8649}\x{864A}\x{864B}\x{864C}\x{864D}' - . '\x{864E}\x{864F}\x{8650}\x{8651}\x{8652}\x{8653}\x{8654}\x{8655}\x{8656}' - . '\x{8658}\x{8659}\x{865A}\x{865B}\x{865C}\x{865D}\x{865E}\x{865F}\x{8660}' - . '\x{8661}\x{8662}\x{8663}\x{8664}\x{8665}\x{8666}\x{8667}\x{8668}\x{8669}' - . '\x{866A}\x{866B}\x{866C}\x{866D}\x{866E}\x{866F}\x{8670}\x{8671}\x{8672}' - . '\x{8673}\x{8674}\x{8676}\x{8677}\x{8678}\x{8679}\x{867A}\x{867B}\x{867C}' - . '\x{867D}\x{867E}\x{867F}\x{8680}\x{8681}\x{8682}\x{8683}\x{8684}\x{8685}' - . '\x{8686}\x{8687}\x{8688}\x{868A}\x{868B}\x{868C}\x{868D}\x{868E}\x{868F}' - . '\x{8690}\x{8691}\x{8693}\x{8694}\x{8695}\x{8696}\x{8697}\x{8698}\x{8699}' - . '\x{869A}\x{869B}\x{869C}\x{869D}\x{869E}\x{869F}\x{86A1}\x{86A2}\x{86A3}' - . '\x{86A4}\x{86A5}\x{86A7}\x{86A8}\x{86A9}\x{86AA}\x{86AB}\x{86AC}\x{86AD}' - . '\x{86AE}\x{86AF}\x{86B0}\x{86B1}\x{86B2}\x{86B3}\x{86B4}\x{86B5}\x{86B6}' - . '\x{86B7}\x{86B8}\x{86B9}\x{86BA}\x{86BB}\x{86BC}\x{86BD}\x{86BE}\x{86BF}' - . '\x{86C0}\x{86C1}\x{86C2}\x{86C3}\x{86C4}\x{86C5}\x{86C6}\x{86C7}\x{86C8}' - . '\x{86C9}\x{86CA}\x{86CB}\x{86CC}\x{86CE}\x{86CF}\x{86D0}\x{86D1}\x{86D2}' - . '\x{86D3}\x{86D4}\x{86D6}\x{86D7}\x{86D8}\x{86D9}\x{86DA}\x{86DB}\x{86DC}' - . '\x{86DD}\x{86DE}\x{86DF}\x{86E1}\x{86E2}\x{86E3}\x{86E4}\x{86E5}\x{86E6}' - . '\x{86E8}\x{86E9}\x{86EA}\x{86EB}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F0}' - . '\x{86F1}\x{86F2}\x{86F3}\x{86F4}\x{86F5}\x{86F6}\x{86F7}\x{86F8}\x{86F9}' - . '\x{86FA}\x{86FB}\x{86FC}\x{86FE}\x{86FF}\x{8700}\x{8701}\x{8702}\x{8703}' - . '\x{8704}\x{8705}\x{8706}\x{8707}\x{8708}\x{8709}\x{870A}\x{870B}\x{870C}' - . '\x{870D}\x{870E}\x{870F}\x{8710}\x{8711}\x{8712}\x{8713}\x{8714}\x{8715}' - . '\x{8716}\x{8717}\x{8718}\x{8719}\x{871A}\x{871B}\x{871C}\x{871E}\x{871F}' - . '\x{8720}\x{8721}\x{8722}\x{8723}\x{8724}\x{8725}\x{8726}\x{8727}\x{8728}' - . '\x{8729}\x{872A}\x{872B}\x{872C}\x{872D}\x{872E}\x{8730}\x{8731}\x{8732}' - . '\x{8733}\x{8734}\x{8735}\x{8736}\x{8737}\x{8738}\x{8739}\x{873A}\x{873B}' - . '\x{873C}\x{873E}\x{873F}\x{8740}\x{8741}\x{8742}\x{8743}\x{8744}\x{8746}' - . '\x{8747}\x{8748}\x{8749}\x{874A}\x{874C}\x{874D}\x{874E}\x{874F}\x{8750}' - . '\x{8751}\x{8752}\x{8753}\x{8754}\x{8755}\x{8756}\x{8757}\x{8758}\x{8759}' - . '\x{875A}\x{875B}\x{875C}\x{875D}\x{875E}\x{875F}\x{8760}\x{8761}\x{8762}' - . '\x{8763}\x{8764}\x{8765}\x{8766}\x{8767}\x{8768}\x{8769}\x{876A}\x{876B}' - . '\x{876C}\x{876D}\x{876E}\x{876F}\x{8770}\x{8772}\x{8773}\x{8774}\x{8775}' - . '\x{8776}\x{8777}\x{8778}\x{8779}\x{877A}\x{877B}\x{877C}\x{877D}\x{877E}' - . '\x{8780}\x{8781}\x{8782}\x{8783}\x{8784}\x{8785}\x{8786}\x{8787}\x{8788}' - . '\x{8789}\x{878A}\x{878B}\x{878C}\x{878D}\x{878F}\x{8790}\x{8791}\x{8792}' - . '\x{8793}\x{8794}\x{8795}\x{8796}\x{8797}\x{8798}\x{879A}\x{879B}\x{879C}' - . '\x{879D}\x{879E}\x{879F}\x{87A0}\x{87A1}\x{87A2}\x{87A3}\x{87A4}\x{87A5}' - . '\x{87A6}\x{87A7}\x{87A8}\x{87A9}\x{87AA}\x{87AB}\x{87AC}\x{87AD}\x{87AE}' - . '\x{87AF}\x{87B0}\x{87B1}\x{87B2}\x{87B3}\x{87B4}\x{87B5}\x{87B6}\x{87B7}' - . '\x{87B8}\x{87B9}\x{87BA}\x{87BB}\x{87BC}\x{87BD}\x{87BE}\x{87BF}\x{87C0}' - . '\x{87C1}\x{87C2}\x{87C3}\x{87C4}\x{87C5}\x{87C6}\x{87C7}\x{87C8}\x{87C9}' - . '\x{87CA}\x{87CB}\x{87CC}\x{87CD}\x{87CE}\x{87CF}\x{87D0}\x{87D1}\x{87D2}' - . '\x{87D3}\x{87D4}\x{87D5}\x{87D6}\x{87D7}\x{87D8}\x{87D9}\x{87DB}\x{87DC}' - . '\x{87DD}\x{87DE}\x{87DF}\x{87E0}\x{87E1}\x{87E2}\x{87E3}\x{87E4}\x{87E5}' - . '\x{87E6}\x{87E7}\x{87E8}\x{87E9}\x{87EA}\x{87EB}\x{87EC}\x{87ED}\x{87EE}' - . '\x{87EF}\x{87F1}\x{87F2}\x{87F3}\x{87F4}\x{87F5}\x{87F6}\x{87F7}\x{87F8}' - . '\x{87F9}\x{87FA}\x{87FB}\x{87FC}\x{87FD}\x{87FE}\x{87FF}\x{8800}\x{8801}' - . '\x{8802}\x{8803}\x{8804}\x{8805}\x{8806}\x{8808}\x{8809}\x{880A}\x{880B}' - . '\x{880C}\x{880D}\x{880E}\x{880F}\x{8810}\x{8811}\x{8813}\x{8814}\x{8815}' - . '\x{8816}\x{8817}\x{8818}\x{8819}\x{881A}\x{881B}\x{881C}\x{881D}\x{881E}' - . '\x{881F}\x{8820}\x{8821}\x{8822}\x{8823}\x{8824}\x{8825}\x{8826}\x{8827}' - . '\x{8828}\x{8829}\x{882A}\x{882B}\x{882C}\x{882E}\x{882F}\x{8830}\x{8831}' - . '\x{8832}\x{8833}\x{8834}\x{8835}\x{8836}\x{8837}\x{8838}\x{8839}\x{883B}' - . '\x{883C}\x{883D}\x{883E}\x{883F}\x{8840}\x{8841}\x{8842}\x{8843}\x{8844}' - . '\x{8845}\x{8846}\x{8848}\x{8849}\x{884A}\x{884B}\x{884C}\x{884D}\x{884E}' - . '\x{884F}\x{8850}\x{8851}\x{8852}\x{8853}\x{8854}\x{8855}\x{8856}\x{8857}' - . '\x{8859}\x{885A}\x{885B}\x{885D}\x{885E}\x{8860}\x{8861}\x{8862}\x{8863}' - . '\x{8864}\x{8865}\x{8866}\x{8867}\x{8868}\x{8869}\x{886A}\x{886B}\x{886C}' - . '\x{886D}\x{886E}\x{886F}\x{8870}\x{8871}\x{8872}\x{8873}\x{8874}\x{8875}' - . '\x{8876}\x{8877}\x{8878}\x{8879}\x{887B}\x{887C}\x{887D}\x{887E}\x{887F}' - . '\x{8880}\x{8881}\x{8882}\x{8883}\x{8884}\x{8885}\x{8886}\x{8887}\x{8888}' - . '\x{8889}\x{888A}\x{888B}\x{888C}\x{888D}\x{888E}\x{888F}\x{8890}\x{8891}' - . '\x{8892}\x{8893}\x{8894}\x{8895}\x{8896}\x{8897}\x{8898}\x{8899}\x{889A}' - . '\x{889B}\x{889C}\x{889D}\x{889E}\x{889F}\x{88A0}\x{88A1}\x{88A2}\x{88A3}' - . '\x{88A4}\x{88A5}\x{88A6}\x{88A7}\x{88A8}\x{88A9}\x{88AA}\x{88AB}\x{88AC}' - . '\x{88AD}\x{88AE}\x{88AF}\x{88B0}\x{88B1}\x{88B2}\x{88B3}\x{88B4}\x{88B6}' - . '\x{88B7}\x{88B8}\x{88B9}\x{88BA}\x{88BB}\x{88BC}\x{88BD}\x{88BE}\x{88BF}' - . '\x{88C0}\x{88C1}\x{88C2}\x{88C3}\x{88C4}\x{88C5}\x{88C6}\x{88C7}\x{88C8}' - . '\x{88C9}\x{88CA}\x{88CB}\x{88CC}\x{88CD}\x{88CE}\x{88CF}\x{88D0}\x{88D1}' - . '\x{88D2}\x{88D3}\x{88D4}\x{88D5}\x{88D6}\x{88D7}\x{88D8}\x{88D9}\x{88DA}' - . '\x{88DB}\x{88DC}\x{88DD}\x{88DE}\x{88DF}\x{88E0}\x{88E1}\x{88E2}\x{88E3}' - . '\x{88E4}\x{88E5}\x{88E7}\x{88E8}\x{88EA}\x{88EB}\x{88EC}\x{88EE}\x{88EF}' - . '\x{88F0}\x{88F1}\x{88F2}\x{88F3}\x{88F4}\x{88F5}\x{88F6}\x{88F7}\x{88F8}' - . '\x{88F9}\x{88FA}\x{88FB}\x{88FC}\x{88FD}\x{88FE}\x{88FF}\x{8900}\x{8901}' - . '\x{8902}\x{8904}\x{8905}\x{8906}\x{8907}\x{8908}\x{8909}\x{890A}\x{890B}' - . '\x{890C}\x{890D}\x{890E}\x{8910}\x{8911}\x{8912}\x{8913}\x{8914}\x{8915}' - . '\x{8916}\x{8917}\x{8918}\x{8919}\x{891A}\x{891B}\x{891C}\x{891D}\x{891E}' - . '\x{891F}\x{8920}\x{8921}\x{8922}\x{8923}\x{8925}\x{8926}\x{8927}\x{8928}' - . '\x{8929}\x{892A}\x{892B}\x{892C}\x{892D}\x{892E}\x{892F}\x{8930}\x{8931}' - . '\x{8932}\x{8933}\x{8934}\x{8935}\x{8936}\x{8937}\x{8938}\x{8939}\x{893A}' - . '\x{893B}\x{893C}\x{893D}\x{893E}\x{893F}\x{8940}\x{8941}\x{8942}\x{8943}' - . '\x{8944}\x{8945}\x{8946}\x{8947}\x{8948}\x{8949}\x{894A}\x{894B}\x{894C}' - . '\x{894E}\x{894F}\x{8950}\x{8951}\x{8952}\x{8953}\x{8954}\x{8955}\x{8956}' - . '\x{8957}\x{8958}\x{8959}\x{895A}\x{895B}\x{895C}\x{895D}\x{895E}\x{895F}' - . '\x{8960}\x{8961}\x{8962}\x{8963}\x{8964}\x{8966}\x{8967}\x{8968}\x{8969}' - . '\x{896A}\x{896B}\x{896C}\x{896D}\x{896E}\x{896F}\x{8970}\x{8971}\x{8972}' - . '\x{8973}\x{8974}\x{8976}\x{8977}\x{8978}\x{8979}\x{897A}\x{897B}\x{897C}' - . '\x{897E}\x{897F}\x{8980}\x{8981}\x{8982}\x{8983}\x{8984}\x{8985}\x{8986}' - . '\x{8987}\x{8988}\x{8989}\x{898A}\x{898B}\x{898C}\x{898E}\x{898F}\x{8991}' - . '\x{8992}\x{8993}\x{8995}\x{8996}\x{8997}\x{8998}\x{899A}\x{899B}\x{899C}' - . '\x{899D}\x{899E}\x{899F}\x{89A0}\x{89A1}\x{89A2}\x{89A3}\x{89A4}\x{89A5}' - . '\x{89A6}\x{89A7}\x{89A8}\x{89AA}\x{89AB}\x{89AC}\x{89AD}\x{89AE}\x{89AF}' - . '\x{89B1}\x{89B2}\x{89B3}\x{89B5}\x{89B6}\x{89B7}\x{89B8}\x{89B9}\x{89BA}' - . '\x{89BD}\x{89BE}\x{89BF}\x{89C0}\x{89C1}\x{89C2}\x{89C3}\x{89C4}\x{89C5}' - . '\x{89C6}\x{89C7}\x{89C8}\x{89C9}\x{89CA}\x{89CB}\x{89CC}\x{89CD}\x{89CE}' - . '\x{89CF}\x{89D0}\x{89D1}\x{89D2}\x{89D3}\x{89D4}\x{89D5}\x{89D6}\x{89D7}' - . '\x{89D8}\x{89D9}\x{89DA}\x{89DB}\x{89DC}\x{89DD}\x{89DE}\x{89DF}\x{89E0}' - . '\x{89E1}\x{89E2}\x{89E3}\x{89E4}\x{89E5}\x{89E6}\x{89E7}\x{89E8}\x{89E9}' - . '\x{89EA}\x{89EB}\x{89EC}\x{89ED}\x{89EF}\x{89F0}\x{89F1}\x{89F2}\x{89F3}' - . '\x{89F4}\x{89F6}\x{89F7}\x{89F8}\x{89FA}\x{89FB}\x{89FC}\x{89FE}\x{89FF}' - . '\x{8A00}\x{8A01}\x{8A02}\x{8A03}\x{8A04}\x{8A07}\x{8A08}\x{8A09}\x{8A0A}' - . '\x{8A0B}\x{8A0C}\x{8A0D}\x{8A0E}\x{8A0F}\x{8A10}\x{8A11}\x{8A12}\x{8A13}' - . '\x{8A15}\x{8A16}\x{8A17}\x{8A18}\x{8A1A}\x{8A1B}\x{8A1C}\x{8A1D}\x{8A1E}' - . '\x{8A1F}\x{8A22}\x{8A23}\x{8A24}\x{8A25}\x{8A26}\x{8A27}\x{8A28}\x{8A29}' - . '\x{8A2A}\x{8A2C}\x{8A2D}\x{8A2E}\x{8A2F}\x{8A30}\x{8A31}\x{8A32}\x{8A34}' - . '\x{8A35}\x{8A36}\x{8A37}\x{8A38}\x{8A39}\x{8A3A}\x{8A3B}\x{8A3C}\x{8A3E}' - . '\x{8A3F}\x{8A40}\x{8A41}\x{8A42}\x{8A43}\x{8A44}\x{8A45}\x{8A46}\x{8A47}' - . '\x{8A48}\x{8A49}\x{8A4A}\x{8A4C}\x{8A4D}\x{8A4E}\x{8A4F}\x{8A50}\x{8A51}' - . '\x{8A52}\x{8A53}\x{8A54}\x{8A55}\x{8A56}\x{8A57}\x{8A58}\x{8A59}\x{8A5A}' - . '\x{8A5B}\x{8A5C}\x{8A5D}\x{8A5E}\x{8A5F}\x{8A60}\x{8A61}\x{8A62}\x{8A63}' - . '\x{8A65}\x{8A66}\x{8A67}\x{8A68}\x{8A69}\x{8A6A}\x{8A6B}\x{8A6C}\x{8A6D}' - . '\x{8A6E}\x{8A6F}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A74}\x{8A75}\x{8A76}' - . '\x{8A77}\x{8A79}\x{8A7A}\x{8A7B}\x{8A7C}\x{8A7E}\x{8A7F}\x{8A80}\x{8A81}' - . '\x{8A82}\x{8A83}\x{8A84}\x{8A85}\x{8A86}\x{8A87}\x{8A89}\x{8A8A}\x{8A8B}' - . '\x{8A8C}\x{8A8D}\x{8A8E}\x{8A8F}\x{8A90}\x{8A91}\x{8A92}\x{8A93}\x{8A94}' - . '\x{8A95}\x{8A96}\x{8A97}\x{8A98}\x{8A99}\x{8A9A}\x{8A9B}\x{8A9C}\x{8A9D}' - . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA2}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA7}' - . '\x{8AA8}\x{8AA9}\x{8AAA}\x{8AAB}\x{8AAC}\x{8AAE}\x{8AB0}\x{8AB1}\x{8AB2}' - . '\x{8AB3}\x{8AB4}\x{8AB5}\x{8AB6}\x{8AB8}\x{8AB9}\x{8ABA}\x{8ABB}\x{8ABC}' - . '\x{8ABD}\x{8ABE}\x{8ABF}\x{8AC0}\x{8AC1}\x{8AC2}\x{8AC3}\x{8AC4}\x{8AC5}' - . '\x{8AC6}\x{8AC7}\x{8AC8}\x{8AC9}\x{8ACA}\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACE}' - . '\x{8ACF}\x{8AD1}\x{8AD2}\x{8AD3}\x{8AD4}\x{8AD5}\x{8AD6}\x{8AD7}\x{8AD8}' - . '\x{8AD9}\x{8ADA}\x{8ADB}\x{8ADC}\x{8ADD}\x{8ADE}\x{8ADF}\x{8AE0}\x{8AE1}' - . '\x{8AE2}\x{8AE3}\x{8AE4}\x{8AE5}\x{8AE6}\x{8AE7}\x{8AE8}\x{8AE9}\x{8AEA}' - . '\x{8AEB}\x{8AED}\x{8AEE}\x{8AEF}\x{8AF0}\x{8AF1}\x{8AF2}\x{8AF3}\x{8AF4}' - . '\x{8AF5}\x{8AF6}\x{8AF7}\x{8AF8}\x{8AF9}\x{8AFA}\x{8AFB}\x{8AFC}\x{8AFD}' - . '\x{8AFE}\x{8AFF}\x{8B00}\x{8B01}\x{8B02}\x{8B03}\x{8B04}\x{8B05}\x{8B06}' - . '\x{8B07}\x{8B08}\x{8B09}\x{8B0A}\x{8B0B}\x{8B0D}\x{8B0E}\x{8B0F}\x{8B10}' - . '\x{8B11}\x{8B12}\x{8B13}\x{8B14}\x{8B15}\x{8B16}\x{8B17}\x{8B18}\x{8B19}' - . '\x{8B1A}\x{8B1B}\x{8B1C}\x{8B1D}\x{8B1E}\x{8B1F}\x{8B20}\x{8B21}\x{8B22}' - . '\x{8B23}\x{8B24}\x{8B25}\x{8B26}\x{8B27}\x{8B28}\x{8B2A}\x{8B2B}\x{8B2C}' - . '\x{8B2D}\x{8B2E}\x{8B2F}\x{8B30}\x{8B31}\x{8B33}\x{8B34}\x{8B35}\x{8B36}' - . '\x{8B37}\x{8B39}\x{8B3A}\x{8B3B}\x{8B3C}\x{8B3D}\x{8B3E}\x{8B40}\x{8B41}' - . '\x{8B42}\x{8B43}\x{8B44}\x{8B45}\x{8B46}\x{8B47}\x{8B48}\x{8B49}\x{8B4A}' - . '\x{8B4B}\x{8B4C}\x{8B4D}\x{8B4E}\x{8B4F}\x{8B50}\x{8B51}\x{8B52}\x{8B53}' - . '\x{8B54}\x{8B55}\x{8B56}\x{8B57}\x{8B58}\x{8B59}\x{8B5A}\x{8B5B}\x{8B5C}' - . '\x{8B5D}\x{8B5E}\x{8B5F}\x{8B60}\x{8B63}\x{8B64}\x{8B65}\x{8B66}\x{8B67}' - . '\x{8B68}\x{8B6A}\x{8B6B}\x{8B6C}\x{8B6D}\x{8B6E}\x{8B6F}\x{8B70}\x{8B71}' - . '\x{8B73}\x{8B74}\x{8B76}\x{8B77}\x{8B78}\x{8B79}\x{8B7A}\x{8B7B}\x{8B7D}' - . '\x{8B7E}\x{8B7F}\x{8B80}\x{8B82}\x{8B83}\x{8B84}\x{8B85}\x{8B86}\x{8B88}' - . '\x{8B89}\x{8B8A}\x{8B8B}\x{8B8C}\x{8B8E}\x{8B90}\x{8B91}\x{8B92}\x{8B93}' - . '\x{8B94}\x{8B95}\x{8B96}\x{8B97}\x{8B98}\x{8B99}\x{8B9A}\x{8B9C}\x{8B9D}' - . '\x{8B9E}\x{8B9F}\x{8BA0}\x{8BA1}\x{8BA2}\x{8BA3}\x{8BA4}\x{8BA5}\x{8BA6}' - . '\x{8BA7}\x{8BA8}\x{8BA9}\x{8BAA}\x{8BAB}\x{8BAC}\x{8BAD}\x{8BAE}\x{8BAF}' - . '\x{8BB0}\x{8BB1}\x{8BB2}\x{8BB3}\x{8BB4}\x{8BB5}\x{8BB6}\x{8BB7}\x{8BB8}' - . '\x{8BB9}\x{8BBA}\x{8BBB}\x{8BBC}\x{8BBD}\x{8BBE}\x{8BBF}\x{8BC0}\x{8BC1}' - . '\x{8BC2}\x{8BC3}\x{8BC4}\x{8BC5}\x{8BC6}\x{8BC7}\x{8BC8}\x{8BC9}\x{8BCA}' - . '\x{8BCB}\x{8BCC}\x{8BCD}\x{8BCE}\x{8BCF}\x{8BD0}\x{8BD1}\x{8BD2}\x{8BD3}' - . '\x{8BD4}\x{8BD5}\x{8BD6}\x{8BD7}\x{8BD8}\x{8BD9}\x{8BDA}\x{8BDB}\x{8BDC}' - . '\x{8BDD}\x{8BDE}\x{8BDF}\x{8BE0}\x{8BE1}\x{8BE2}\x{8BE3}\x{8BE4}\x{8BE5}' - . '\x{8BE6}\x{8BE7}\x{8BE8}\x{8BE9}\x{8BEA}\x{8BEB}\x{8BEC}\x{8BED}\x{8BEE}' - . '\x{8BEF}\x{8BF0}\x{8BF1}\x{8BF2}\x{8BF3}\x{8BF4}\x{8BF5}\x{8BF6}\x{8BF7}' - . '\x{8BF8}\x{8BF9}\x{8BFA}\x{8BFB}\x{8BFC}\x{8BFD}\x{8BFE}\x{8BFF}\x{8C00}' - . '\x{8C01}\x{8C02}\x{8C03}\x{8C04}\x{8C05}\x{8C06}\x{8C07}\x{8C08}\x{8C09}' - . '\x{8C0A}\x{8C0B}\x{8C0C}\x{8C0D}\x{8C0E}\x{8C0F}\x{8C10}\x{8C11}\x{8C12}' - . '\x{8C13}\x{8C14}\x{8C15}\x{8C16}\x{8C17}\x{8C18}\x{8C19}\x{8C1A}\x{8C1B}' - . '\x{8C1C}\x{8C1D}\x{8C1E}\x{8C1F}\x{8C20}\x{8C21}\x{8C22}\x{8C23}\x{8C24}' - . '\x{8C25}\x{8C26}\x{8C27}\x{8C28}\x{8C29}\x{8C2A}\x{8C2B}\x{8C2C}\x{8C2D}' - . '\x{8C2E}\x{8C2F}\x{8C30}\x{8C31}\x{8C32}\x{8C33}\x{8C34}\x{8C35}\x{8C36}' - . '\x{8C37}\x{8C39}\x{8C3A}\x{8C3B}\x{8C3C}\x{8C3D}\x{8C3E}\x{8C3F}\x{8C41}' - . '\x{8C42}\x{8C43}\x{8C45}\x{8C46}\x{8C47}\x{8C48}\x{8C49}\x{8C4A}\x{8C4B}' - . '\x{8C4C}\x{8C4D}\x{8C4E}\x{8C4F}\x{8C50}\x{8C54}\x{8C55}\x{8C56}\x{8C57}' - . '\x{8C59}\x{8C5A}\x{8C5B}\x{8C5C}\x{8C5D}\x{8C5E}\x{8C5F}\x{8C60}\x{8C61}' - . '\x{8C62}\x{8C63}\x{8C64}\x{8C65}\x{8C66}\x{8C67}\x{8C68}\x{8C69}\x{8C6A}' - . '\x{8C6B}\x{8C6C}\x{8C6D}\x{8C6E}\x{8C6F}\x{8C70}\x{8C71}\x{8C72}\x{8C73}' - . '\x{8C75}\x{8C76}\x{8C77}\x{8C78}\x{8C79}\x{8C7A}\x{8C7B}\x{8C7D}\x{8C7E}' - . '\x{8C80}\x{8C81}\x{8C82}\x{8C84}\x{8C85}\x{8C86}\x{8C88}\x{8C89}\x{8C8A}' - . '\x{8C8C}\x{8C8D}\x{8C8F}\x{8C90}\x{8C91}\x{8C92}\x{8C93}\x{8C94}\x{8C95}' - . '\x{8C96}\x{8C97}\x{8C98}\x{8C99}\x{8C9A}\x{8C9C}\x{8C9D}\x{8C9E}\x{8C9F}' - . '\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA3}\x{8CA4}\x{8CA5}\x{8CA7}\x{8CA8}\x{8CA9}' - . '\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}\x{8CB1}\x{8CB2}' - . '\x{8CB3}\x{8CB4}\x{8CB5}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CB9}\x{8CBA}\x{8CBB}' - . '\x{8CBC}\x{8CBD}\x{8CBE}\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}' - . '\x{8CC5}\x{8CC6}\x{8CC7}\x{8CC8}\x{8CC9}\x{8CCA}\x{8CCC}\x{8CCE}\x{8CCF}' - . '\x{8CD0}\x{8CD1}\x{8CD2}\x{8CD3}\x{8CD4}\x{8CD5}\x{8CD7}\x{8CD9}\x{8CDA}' - . '\x{8CDB}\x{8CDC}\x{8CDD}\x{8CDE}\x{8CDF}\x{8CE0}\x{8CE1}\x{8CE2}\x{8CE3}' - . '\x{8CE4}\x{8CE5}\x{8CE6}\x{8CE7}\x{8CE8}\x{8CEA}\x{8CEB}\x{8CEC}\x{8CED}' - . '\x{8CEE}\x{8CEF}\x{8CF0}\x{8CF1}\x{8CF2}\x{8CF3}\x{8CF4}\x{8CF5}\x{8CF6}' - . '\x{8CF8}\x{8CF9}\x{8CFA}\x{8CFB}\x{8CFC}\x{8CFD}\x{8CFE}\x{8CFF}\x{8D00}' - . '\x{8D02}\x{8D03}\x{8D04}\x{8D05}\x{8D06}\x{8D07}\x{8D08}\x{8D09}\x{8D0A}' - . '\x{8D0B}\x{8D0C}\x{8D0D}\x{8D0E}\x{8D0F}\x{8D10}\x{8D13}\x{8D14}\x{8D15}' - . '\x{8D16}\x{8D17}\x{8D18}\x{8D19}\x{8D1A}\x{8D1B}\x{8D1C}\x{8D1D}\x{8D1E}' - . '\x{8D1F}\x{8D20}\x{8D21}\x{8D22}\x{8D23}\x{8D24}\x{8D25}\x{8D26}\x{8D27}' - . '\x{8D28}\x{8D29}\x{8D2A}\x{8D2B}\x{8D2C}\x{8D2D}\x{8D2E}\x{8D2F}\x{8D30}' - . '\x{8D31}\x{8D32}\x{8D33}\x{8D34}\x{8D35}\x{8D36}\x{8D37}\x{8D38}\x{8D39}' - . '\x{8D3A}\x{8D3B}\x{8D3C}\x{8D3D}\x{8D3E}\x{8D3F}\x{8D40}\x{8D41}\x{8D42}' - . '\x{8D43}\x{8D44}\x{8D45}\x{8D46}\x{8D47}\x{8D48}\x{8D49}\x{8D4A}\x{8D4B}' - . '\x{8D4C}\x{8D4D}\x{8D4E}\x{8D4F}\x{8D50}\x{8D51}\x{8D52}\x{8D53}\x{8D54}' - . '\x{8D55}\x{8D56}\x{8D57}\x{8D58}\x{8D59}\x{8D5A}\x{8D5B}\x{8D5C}\x{8D5D}' - . '\x{8D5E}\x{8D5F}\x{8D60}\x{8D61}\x{8D62}\x{8D63}\x{8D64}\x{8D65}\x{8D66}' - . '\x{8D67}\x{8D68}\x{8D69}\x{8D6A}\x{8D6B}\x{8D6C}\x{8D6D}\x{8D6E}\x{8D6F}' - . '\x{8D70}\x{8D71}\x{8D72}\x{8D73}\x{8D74}\x{8D75}\x{8D76}\x{8D77}\x{8D78}' - . '\x{8D79}\x{8D7A}\x{8D7B}\x{8D7D}\x{8D7E}\x{8D7F}\x{8D80}\x{8D81}\x{8D82}' - . '\x{8D83}\x{8D84}\x{8D85}\x{8D86}\x{8D87}\x{8D88}\x{8D89}\x{8D8A}\x{8D8B}' - . '\x{8D8C}\x{8D8D}\x{8D8E}\x{8D8F}\x{8D90}\x{8D91}\x{8D92}\x{8D93}\x{8D94}' - . '\x{8D95}\x{8D96}\x{8D97}\x{8D98}\x{8D99}\x{8D9A}\x{8D9B}\x{8D9C}\x{8D9D}' - . '\x{8D9E}\x{8D9F}\x{8DA0}\x{8DA1}\x{8DA2}\x{8DA3}\x{8DA4}\x{8DA5}\x{8DA7}' - . '\x{8DA8}\x{8DA9}\x{8DAA}\x{8DAB}\x{8DAC}\x{8DAD}\x{8DAE}\x{8DAF}\x{8DB0}' - . '\x{8DB1}\x{8DB2}\x{8DB3}\x{8DB4}\x{8DB5}\x{8DB6}\x{8DB7}\x{8DB8}\x{8DB9}' - . '\x{8DBA}\x{8DBB}\x{8DBC}\x{8DBD}\x{8DBE}\x{8DBF}\x{8DC1}\x{8DC2}\x{8DC3}' - . '\x{8DC4}\x{8DC5}\x{8DC6}\x{8DC7}\x{8DC8}\x{8DC9}\x{8DCA}\x{8DCB}\x{8DCC}' - . '\x{8DCD}\x{8DCE}\x{8DCF}\x{8DD0}\x{8DD1}\x{8DD2}\x{8DD3}\x{8DD4}\x{8DD5}' - . '\x{8DD6}\x{8DD7}\x{8DD8}\x{8DD9}\x{8DDA}\x{8DDB}\x{8DDC}\x{8DDD}\x{8DDE}' - . '\x{8DDF}\x{8DE0}\x{8DE1}\x{8DE2}\x{8DE3}\x{8DE4}\x{8DE6}\x{8DE7}\x{8DE8}' - . '\x{8DE9}\x{8DEA}\x{8DEB}\x{8DEC}\x{8DED}\x{8DEE}\x{8DEF}\x{8DF0}\x{8DF1}' - . '\x{8DF2}\x{8DF3}\x{8DF4}\x{8DF5}\x{8DF6}\x{8DF7}\x{8DF8}\x{8DF9}\x{8DFA}' - . '\x{8DFB}\x{8DFC}\x{8DFD}\x{8DFE}\x{8DFF}\x{8E00}\x{8E02}\x{8E03}\x{8E04}' - . '\x{8E05}\x{8E06}\x{8E07}\x{8E08}\x{8E09}\x{8E0A}\x{8E0C}\x{8E0D}\x{8E0E}' - . '\x{8E0F}\x{8E10}\x{8E11}\x{8E12}\x{8E13}\x{8E14}\x{8E15}\x{8E16}\x{8E17}' - . '\x{8E18}\x{8E19}\x{8E1A}\x{8E1B}\x{8E1C}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E20}' - . '\x{8E21}\x{8E22}\x{8E23}\x{8E24}\x{8E25}\x{8E26}\x{8E27}\x{8E28}\x{8E29}' - . '\x{8E2A}\x{8E2B}\x{8E2C}\x{8E2D}\x{8E2E}\x{8E2F}\x{8E30}\x{8E31}\x{8E33}' - . '\x{8E34}\x{8E35}\x{8E36}\x{8E37}\x{8E38}\x{8E39}\x{8E3A}\x{8E3B}\x{8E3C}' - . '\x{8E3D}\x{8E3E}\x{8E3F}\x{8E40}\x{8E41}\x{8E42}\x{8E43}\x{8E44}\x{8E45}' - . '\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4B}\x{8E4C}\x{8E4D}\x{8E4E}\x{8E50}' - . '\x{8E51}\x{8E52}\x{8E53}\x{8E54}\x{8E55}\x{8E56}\x{8E57}\x{8E58}\x{8E59}' - . '\x{8E5A}\x{8E5B}\x{8E5C}\x{8E5D}\x{8E5E}\x{8E5F}\x{8E60}\x{8E61}\x{8E62}' - . '\x{8E63}\x{8E64}\x{8E65}\x{8E66}\x{8E67}\x{8E68}\x{8E69}\x{8E6A}\x{8E6B}' - . '\x{8E6C}\x{8E6D}\x{8E6F}\x{8E70}\x{8E71}\x{8E72}\x{8E73}\x{8E74}\x{8E76}' - . '\x{8E78}\x{8E7A}\x{8E7B}\x{8E7C}\x{8E7D}\x{8E7E}\x{8E7F}\x{8E80}\x{8E81}' - . '\x{8E82}\x{8E83}\x{8E84}\x{8E85}\x{8E86}\x{8E87}\x{8E88}\x{8E89}\x{8E8A}' - . '\x{8E8B}\x{8E8C}\x{8E8D}\x{8E8E}\x{8E8F}\x{8E90}\x{8E91}\x{8E92}\x{8E93}' - . '\x{8E94}\x{8E95}\x{8E96}\x{8E97}\x{8E98}\x{8E9A}\x{8E9C}\x{8E9D}\x{8E9E}' - . '\x{8E9F}\x{8EA0}\x{8EA1}\x{8EA3}\x{8EA4}\x{8EA5}\x{8EA6}\x{8EA7}\x{8EA8}' - . '\x{8EA9}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAD}\x{8EAE}\x{8EAF}\x{8EB0}\x{8EB1}' - . '\x{8EB2}\x{8EB4}\x{8EB5}\x{8EB8}\x{8EB9}\x{8EBA}\x{8EBB}\x{8EBC}\x{8EBD}' - . '\x{8EBE}\x{8EBF}\x{8EC0}\x{8EC2}\x{8EC3}\x{8EC5}\x{8EC6}\x{8EC7}\x{8EC8}' - . '\x{8EC9}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ECE}\x{8ECF}\x{8ED0}\x{8ED1}' - . '\x{8ED2}\x{8ED3}\x{8ED4}\x{8ED5}\x{8ED6}\x{8ED7}\x{8ED8}\x{8EDA}\x{8EDB}' - . '\x{8EDC}\x{8EDD}\x{8EDE}\x{8EDF}\x{8EE0}\x{8EE1}\x{8EE4}\x{8EE5}\x{8EE6}' - . '\x{8EE7}\x{8EE8}\x{8EE9}\x{8EEA}\x{8EEB}\x{8EEC}\x{8EED}\x{8EEE}\x{8EEF}' - . '\x{8EF1}\x{8EF2}\x{8EF3}\x{8EF4}\x{8EF5}\x{8EF6}\x{8EF7}\x{8EF8}\x{8EF9}' - . '\x{8EFA}\x{8EFB}\x{8EFC}\x{8EFD}\x{8EFE}\x{8EFF}\x{8F00}\x{8F01}\x{8F02}' - . '\x{8F03}\x{8F04}\x{8F05}\x{8F06}\x{8F07}\x{8F08}\x{8F09}\x{8F0A}\x{8F0B}' - . '\x{8F0D}\x{8F0E}\x{8F10}\x{8F11}\x{8F12}\x{8F13}\x{8F14}\x{8F15}\x{8F16}' - . '\x{8F17}\x{8F18}\x{8F1A}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1E}\x{8F1F}\x{8F20}' - . '\x{8F21}\x{8F22}\x{8F23}\x{8F24}\x{8F25}\x{8F26}\x{8F27}\x{8F28}\x{8F29}' - . '\x{8F2A}\x{8F2B}\x{8F2C}\x{8F2E}\x{8F2F}\x{8F30}\x{8F31}\x{8F32}\x{8F33}' - . '\x{8F34}\x{8F35}\x{8F36}\x{8F37}\x{8F38}\x{8F39}\x{8F3B}\x{8F3C}\x{8F3D}' - . '\x{8F3E}\x{8F3F}\x{8F40}\x{8F42}\x{8F43}\x{8F44}\x{8F45}\x{8F46}\x{8F47}' - . '\x{8F48}\x{8F49}\x{8F4A}\x{8F4B}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F4F}\x{8F50}' - . '\x{8F51}\x{8F52}\x{8F53}\x{8F54}\x{8F55}\x{8F56}\x{8F57}\x{8F58}\x{8F59}' - . '\x{8F5A}\x{8F5B}\x{8F5D}\x{8F5E}\x{8F5F}\x{8F60}\x{8F61}\x{8F62}\x{8F63}' - . '\x{8F64}\x{8F65}\x{8F66}\x{8F67}\x{8F68}\x{8F69}\x{8F6A}\x{8F6B}\x{8F6C}' - . '\x{8F6D}\x{8F6E}\x{8F6F}\x{8F70}\x{8F71}\x{8F72}\x{8F73}\x{8F74}\x{8F75}' - . '\x{8F76}\x{8F77}\x{8F78}\x{8F79}\x{8F7A}\x{8F7B}\x{8F7C}\x{8F7D}\x{8F7E}' - . '\x{8F7F}\x{8F80}\x{8F81}\x{8F82}\x{8F83}\x{8F84}\x{8F85}\x{8F86}\x{8F87}' - . '\x{8F88}\x{8F89}\x{8F8A}\x{8F8B}\x{8F8C}\x{8F8D}\x{8F8E}\x{8F8F}\x{8F90}' - . '\x{8F91}\x{8F92}\x{8F93}\x{8F94}\x{8F95}\x{8F96}\x{8F97}\x{8F98}\x{8F99}' - . '\x{8F9A}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA0}\x{8FA1}\x{8FA2}\x{8FA3}' - . '\x{8FA5}\x{8FA6}\x{8FA7}\x{8FA8}\x{8FA9}\x{8FAA}\x{8FAB}\x{8FAC}\x{8FAD}' - . '\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB4}\x{8FB5}\x{8FB6}\x{8FB7}' - . '\x{8FB8}\x{8FB9}\x{8FBB}\x{8FBC}\x{8FBD}\x{8FBE}\x{8FBF}\x{8FC0}\x{8FC1}' - . '\x{8FC2}\x{8FC4}\x{8FC5}\x{8FC6}\x{8FC7}\x{8FC8}\x{8FC9}\x{8FCB}\x{8FCC}' - . '\x{8FCD}\x{8FCE}\x{8FCF}\x{8FD0}\x{8FD1}\x{8FD2}\x{8FD3}\x{8FD4}\x{8FD5}' - . '\x{8FD6}\x{8FD7}\x{8FD8}\x{8FD9}\x{8FDA}\x{8FDB}\x{8FDC}\x{8FDD}\x{8FDE}' - . '\x{8FDF}\x{8FE0}\x{8FE1}\x{8FE2}\x{8FE3}\x{8FE4}\x{8FE5}\x{8FE6}\x{8FE8}' - . '\x{8FE9}\x{8FEA}\x{8FEB}\x{8FEC}\x{8FED}\x{8FEE}\x{8FEF}\x{8FF0}\x{8FF1}' - . '\x{8FF2}\x{8FF3}\x{8FF4}\x{8FF5}\x{8FF6}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}' - . '\x{8FFB}\x{8FFC}\x{8FFD}\x{8FFE}\x{8FFF}\x{9000}\x{9001}\x{9002}\x{9003}' - . '\x{9004}\x{9005}\x{9006}\x{9007}\x{9008}\x{9009}\x{900A}\x{900B}\x{900C}' - . '\x{900D}\x{900F}\x{9010}\x{9011}\x{9012}\x{9013}\x{9014}\x{9015}\x{9016}' - . '\x{9017}\x{9018}\x{9019}\x{901A}\x{901B}\x{901C}\x{901D}\x{901E}\x{901F}' - . '\x{9020}\x{9021}\x{9022}\x{9023}\x{9024}\x{9025}\x{9026}\x{9027}\x{9028}' - . '\x{9029}\x{902B}\x{902D}\x{902E}\x{902F}\x{9030}\x{9031}\x{9032}\x{9033}' - . '\x{9034}\x{9035}\x{9036}\x{9038}\x{903A}\x{903B}\x{903C}\x{903D}\x{903E}' - . '\x{903F}\x{9041}\x{9042}\x{9043}\x{9044}\x{9045}\x{9047}\x{9048}\x{9049}' - . '\x{904A}\x{904B}\x{904C}\x{904D}\x{904E}\x{904F}\x{9050}\x{9051}\x{9052}' - . '\x{9053}\x{9054}\x{9055}\x{9056}\x{9057}\x{9058}\x{9059}\x{905A}\x{905B}' - . '\x{905C}\x{905D}\x{905E}\x{905F}\x{9060}\x{9061}\x{9062}\x{9063}\x{9064}' - . '\x{9065}\x{9066}\x{9067}\x{9068}\x{9069}\x{906A}\x{906B}\x{906C}\x{906D}' - . '\x{906E}\x{906F}\x{9070}\x{9071}\x{9072}\x{9073}\x{9074}\x{9075}\x{9076}' - . '\x{9077}\x{9078}\x{9079}\x{907A}\x{907B}\x{907C}\x{907D}\x{907E}\x{907F}' - . '\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9085}\x{9086}\x{9087}\x{9088}' - . '\x{9089}\x{908A}\x{908B}\x{908C}\x{908D}\x{908E}\x{908F}\x{9090}\x{9091}' - . '\x{9092}\x{9093}\x{9094}\x{9095}\x{9096}\x{9097}\x{9098}\x{9099}\x{909A}' - . '\x{909B}\x{909C}\x{909D}\x{909E}\x{909F}\x{90A0}\x{90A1}\x{90A2}\x{90A3}' - . '\x{90A4}\x{90A5}\x{90A6}\x{90A7}\x{90A8}\x{90A9}\x{90AA}\x{90AC}\x{90AD}' - . '\x{90AE}\x{90AF}\x{90B0}\x{90B1}\x{90B2}\x{90B3}\x{90B4}\x{90B5}\x{90B6}' - . '\x{90B7}\x{90B8}\x{90B9}\x{90BA}\x{90BB}\x{90BC}\x{90BD}\x{90BE}\x{90BF}' - . '\x{90C0}\x{90C1}\x{90C2}\x{90C3}\x{90C4}\x{90C5}\x{90C6}\x{90C7}\x{90C8}' - . '\x{90C9}\x{90CA}\x{90CB}\x{90CE}\x{90CF}\x{90D0}\x{90D1}\x{90D3}\x{90D4}' - . '\x{90D5}\x{90D6}\x{90D7}\x{90D8}\x{90D9}\x{90DA}\x{90DB}\x{90DC}\x{90DD}' - . '\x{90DE}\x{90DF}\x{90E0}\x{90E1}\x{90E2}\x{90E3}\x{90E4}\x{90E5}\x{90E6}' - . '\x{90E7}\x{90E8}\x{90E9}\x{90EA}\x{90EB}\x{90EC}\x{90ED}\x{90EE}\x{90EF}' - . '\x{90F0}\x{90F1}\x{90F2}\x{90F3}\x{90F4}\x{90F5}\x{90F7}\x{90F8}\x{90F9}' - . '\x{90FA}\x{90FB}\x{90FC}\x{90FD}\x{90FE}\x{90FF}\x{9100}\x{9101}\x{9102}' - . '\x{9103}\x{9104}\x{9105}\x{9106}\x{9107}\x{9108}\x{9109}\x{910B}\x{910C}' - . '\x{910D}\x{910E}\x{910F}\x{9110}\x{9111}\x{9112}\x{9113}\x{9114}\x{9115}' - . '\x{9116}\x{9117}\x{9118}\x{9119}\x{911A}\x{911B}\x{911C}\x{911D}\x{911E}' - . '\x{911F}\x{9120}\x{9121}\x{9122}\x{9123}\x{9124}\x{9125}\x{9126}\x{9127}' - . '\x{9128}\x{9129}\x{912A}\x{912B}\x{912C}\x{912D}\x{912E}\x{912F}\x{9130}' - . '\x{9131}\x{9132}\x{9133}\x{9134}\x{9135}\x{9136}\x{9137}\x{9138}\x{9139}' - . '\x{913A}\x{913B}\x{913E}\x{913F}\x{9140}\x{9141}\x{9142}\x{9143}\x{9144}' - . '\x{9145}\x{9146}\x{9147}\x{9148}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}' - . '\x{914E}\x{914F}\x{9150}\x{9151}\x{9152}\x{9153}\x{9154}\x{9155}\x{9156}' - . '\x{9157}\x{9158}\x{915A}\x{915B}\x{915C}\x{915D}\x{915E}\x{915F}\x{9160}' - . '\x{9161}\x{9162}\x{9163}\x{9164}\x{9165}\x{9166}\x{9167}\x{9168}\x{9169}' - . '\x{916A}\x{916B}\x{916C}\x{916D}\x{916E}\x{916F}\x{9170}\x{9171}\x{9172}' - . '\x{9173}\x{9174}\x{9175}\x{9176}\x{9177}\x{9178}\x{9179}\x{917A}\x{917C}' - . '\x{917D}\x{917E}\x{917F}\x{9180}\x{9181}\x{9182}\x{9183}\x{9184}\x{9185}' - . '\x{9186}\x{9187}\x{9188}\x{9189}\x{918A}\x{918B}\x{918C}\x{918D}\x{918E}' - . '\x{918F}\x{9190}\x{9191}\x{9192}\x{9193}\x{9194}\x{9196}\x{9199}\x{919A}' - . '\x{919B}\x{919C}\x{919D}\x{919E}\x{919F}\x{91A0}\x{91A1}\x{91A2}\x{91A3}' - . '\x{91A5}\x{91A6}\x{91A7}\x{91A8}\x{91AA}\x{91AB}\x{91AC}\x{91AD}\x{91AE}' - . '\x{91AF}\x{91B0}\x{91B1}\x{91B2}\x{91B3}\x{91B4}\x{91B5}\x{91B6}\x{91B7}' - . '\x{91B9}\x{91BA}\x{91BB}\x{91BC}\x{91BD}\x{91BE}\x{91C0}\x{91C1}\x{91C2}' - . '\x{91C3}\x{91C5}\x{91C6}\x{91C7}\x{91C9}\x{91CA}\x{91CB}\x{91CC}\x{91CD}' - . '\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D2}\x{91D3}\x{91D4}\x{91D5}\x{91D7}' - . '\x{91D8}\x{91D9}\x{91DA}\x{91DB}\x{91DC}\x{91DD}\x{91DE}\x{91DF}\x{91E2}' - . '\x{91E3}\x{91E4}\x{91E5}\x{91E6}\x{91E7}\x{91E8}\x{91E9}\x{91EA}\x{91EB}' - . '\x{91EC}\x{91ED}\x{91EE}\x{91F0}\x{91F1}\x{91F2}\x{91F3}\x{91F4}\x{91F5}' - . '\x{91F7}\x{91F8}\x{91F9}\x{91FA}\x{91FB}\x{91FD}\x{91FE}\x{91FF}\x{9200}' - . '\x{9201}\x{9202}\x{9203}\x{9204}\x{9205}\x{9206}\x{9207}\x{9208}\x{9209}' - . '\x{920A}\x{920B}\x{920C}\x{920D}\x{920E}\x{920F}\x{9210}\x{9211}\x{9212}' - . '\x{9214}\x{9215}\x{9216}\x{9217}\x{9218}\x{9219}\x{921A}\x{921B}\x{921C}' - . '\x{921D}\x{921E}\x{9220}\x{9221}\x{9223}\x{9224}\x{9225}\x{9226}\x{9227}' - . '\x{9228}\x{9229}\x{922A}\x{922B}\x{922D}\x{922E}\x{922F}\x{9230}\x{9231}' - . '\x{9232}\x{9233}\x{9234}\x{9235}\x{9236}\x{9237}\x{9238}\x{9239}\x{923A}' - . '\x{923B}\x{923C}\x{923D}\x{923E}\x{923F}\x{9240}\x{9241}\x{9242}\x{9245}' - . '\x{9246}\x{9247}\x{9248}\x{9249}\x{924A}\x{924B}\x{924C}\x{924D}\x{924E}' - . '\x{924F}\x{9250}\x{9251}\x{9252}\x{9253}\x{9254}\x{9255}\x{9256}\x{9257}' - . '\x{9258}\x{9259}\x{925A}\x{925B}\x{925C}\x{925D}\x{925E}\x{925F}\x{9260}' - . '\x{9261}\x{9262}\x{9263}\x{9264}\x{9265}\x{9266}\x{9267}\x{9268}\x{926B}' - . '\x{926C}\x{926D}\x{926E}\x{926F}\x{9270}\x{9272}\x{9273}\x{9274}\x{9275}' - . '\x{9276}\x{9277}\x{9278}\x{9279}\x{927A}\x{927B}\x{927C}\x{927D}\x{927E}' - . '\x{927F}\x{9280}\x{9282}\x{9283}\x{9285}\x{9286}\x{9287}\x{9288}\x{9289}' - . '\x{928A}\x{928B}\x{928C}\x{928D}\x{928E}\x{928F}\x{9290}\x{9291}\x{9292}' - . '\x{9293}\x{9294}\x{9295}\x{9296}\x{9297}\x{9298}\x{9299}\x{929A}\x{929B}' - . '\x{929C}\x{929D}\x{929F}\x{92A0}\x{92A1}\x{92A2}\x{92A3}\x{92A4}\x{92A5}' - . '\x{92A6}\x{92A7}\x{92A8}\x{92A9}\x{92AA}\x{92AB}\x{92AC}\x{92AD}\x{92AE}' - . '\x{92AF}\x{92B0}\x{92B1}\x{92B2}\x{92B3}\x{92B4}\x{92B5}\x{92B6}\x{92B7}' - . '\x{92B8}\x{92B9}\x{92BA}\x{92BB}\x{92BC}\x{92BE}\x{92BF}\x{92C0}\x{92C1}' - . '\x{92C2}\x{92C3}\x{92C4}\x{92C5}\x{92C6}\x{92C7}\x{92C8}\x{92C9}\x{92CA}' - . '\x{92CB}\x{92CC}\x{92CD}\x{92CE}\x{92CF}\x{92D0}\x{92D1}\x{92D2}\x{92D3}' - . '\x{92D5}\x{92D6}\x{92D7}\x{92D8}\x{92D9}\x{92DA}\x{92DC}\x{92DD}\x{92DE}' - . '\x{92DF}\x{92E0}\x{92E1}\x{92E3}\x{92E4}\x{92E5}\x{92E6}\x{92E7}\x{92E8}' - . '\x{92E9}\x{92EA}\x{92EB}\x{92EC}\x{92ED}\x{92EE}\x{92EF}\x{92F0}\x{92F1}' - . '\x{92F2}\x{92F3}\x{92F4}\x{92F5}\x{92F6}\x{92F7}\x{92F8}\x{92F9}\x{92FA}' - . '\x{92FB}\x{92FC}\x{92FD}\x{92FE}\x{92FF}\x{9300}\x{9301}\x{9302}\x{9303}' - . '\x{9304}\x{9305}\x{9306}\x{9307}\x{9308}\x{9309}\x{930A}\x{930B}\x{930C}' - . '\x{930D}\x{930E}\x{930F}\x{9310}\x{9311}\x{9312}\x{9313}\x{9314}\x{9315}' - . '\x{9316}\x{9317}\x{9318}\x{9319}\x{931A}\x{931B}\x{931D}\x{931E}\x{931F}' - . '\x{9320}\x{9321}\x{9322}\x{9323}\x{9324}\x{9325}\x{9326}\x{9327}\x{9328}' - . '\x{9329}\x{932A}\x{932B}\x{932D}\x{932E}\x{932F}\x{9332}\x{9333}\x{9334}' - . '\x{9335}\x{9336}\x{9337}\x{9338}\x{9339}\x{933A}\x{933B}\x{933C}\x{933D}' - . '\x{933E}\x{933F}\x{9340}\x{9341}\x{9342}\x{9343}\x{9344}\x{9345}\x{9346}' - . '\x{9347}\x{9348}\x{9349}\x{934A}\x{934B}\x{934C}\x{934D}\x{934E}\x{934F}' - . '\x{9350}\x{9351}\x{9352}\x{9353}\x{9354}\x{9355}\x{9356}\x{9357}\x{9358}' - . '\x{9359}\x{935A}\x{935B}\x{935C}\x{935D}\x{935E}\x{935F}\x{9360}\x{9361}' - . '\x{9363}\x{9364}\x{9365}\x{9366}\x{9367}\x{9369}\x{936A}\x{936C}\x{936D}' - . '\x{936E}\x{9370}\x{9371}\x{9372}\x{9374}\x{9375}\x{9376}\x{9377}\x{9379}' - . '\x{937A}\x{937B}\x{937C}\x{937D}\x{937E}\x{9380}\x{9382}\x{9383}\x{9384}' - . '\x{9385}\x{9386}\x{9387}\x{9388}\x{9389}\x{938A}\x{938C}\x{938D}\x{938E}' - . '\x{938F}\x{9390}\x{9391}\x{9392}\x{9393}\x{9394}\x{9395}\x{9396}\x{9397}' - . '\x{9398}\x{9399}\x{939A}\x{939B}\x{939D}\x{939E}\x{939F}\x{93A1}\x{93A2}' - . '\x{93A3}\x{93A4}\x{93A5}\x{93A6}\x{93A7}\x{93A8}\x{93A9}\x{93AA}\x{93AC}' - . '\x{93AD}\x{93AE}\x{93AF}\x{93B0}\x{93B1}\x{93B2}\x{93B3}\x{93B4}\x{93B5}' - . '\x{93B6}\x{93B7}\x{93B8}\x{93B9}\x{93BA}\x{93BC}\x{93BD}\x{93BE}\x{93BF}' - . '\x{93C0}\x{93C1}\x{93C2}\x{93C3}\x{93C4}\x{93C5}\x{93C6}\x{93C7}\x{93C8}' - . '\x{93C9}\x{93CA}\x{93CB}\x{93CC}\x{93CD}\x{93CE}\x{93CF}\x{93D0}\x{93D1}' - . '\x{93D2}\x{93D3}\x{93D4}\x{93D5}\x{93D6}\x{93D7}\x{93D8}\x{93D9}\x{93DA}' - . '\x{93DB}\x{93DC}\x{93DD}\x{93DE}\x{93DF}\x{93E1}\x{93E2}\x{93E3}\x{93E4}' - . '\x{93E6}\x{93E7}\x{93E8}\x{93E9}\x{93EA}\x{93EB}\x{93EC}\x{93ED}\x{93EE}' - . '\x{93EF}\x{93F0}\x{93F1}\x{93F2}\x{93F4}\x{93F5}\x{93F6}\x{93F7}\x{93F8}' - . '\x{93F9}\x{93FA}\x{93FB}\x{93FC}\x{93FD}\x{93FE}\x{93FF}\x{9400}\x{9401}' - . '\x{9403}\x{9404}\x{9405}\x{9406}\x{9407}\x{9408}\x{9409}\x{940A}\x{940B}' - . '\x{940C}\x{940D}\x{940E}\x{940F}\x{9410}\x{9411}\x{9412}\x{9413}\x{9414}' - . '\x{9415}\x{9416}\x{9418}\x{9419}\x{941B}\x{941D}\x{9420}\x{9422}\x{9423}' - . '\x{9425}\x{9426}\x{9427}\x{9428}\x{9429}\x{942A}\x{942B}\x{942C}\x{942D}' - . '\x{942E}\x{942F}\x{9430}\x{9431}\x{9432}\x{9433}\x{9434}\x{9435}\x{9436}' - . '\x{9437}\x{9438}\x{9439}\x{943A}\x{943B}\x{943C}\x{943D}\x{943E}\x{943F}' - . '\x{9440}\x{9441}\x{9442}\x{9444}\x{9445}\x{9446}\x{9447}\x{9448}\x{9449}' - . '\x{944A}\x{944B}\x{944C}\x{944D}\x{944F}\x{9450}\x{9451}\x{9452}\x{9453}' - . '\x{9454}\x{9455}\x{9456}\x{9457}\x{9458}\x{9459}\x{945B}\x{945C}\x{945D}' - . '\x{945E}\x{945F}\x{9460}\x{9461}\x{9462}\x{9463}\x{9464}\x{9465}\x{9466}' - . '\x{9467}\x{9468}\x{9469}\x{946A}\x{946B}\x{946D}\x{946E}\x{946F}\x{9470}' - . '\x{9471}\x{9472}\x{9473}\x{9474}\x{9475}\x{9476}\x{9477}\x{9478}\x{9479}' - . '\x{947A}\x{947C}\x{947D}\x{947E}\x{947F}\x{9480}\x{9481}\x{9482}\x{9483}' - . '\x{9484}\x{9485}\x{9486}\x{9487}\x{9488}\x{9489}\x{948A}\x{948B}\x{948C}' - . '\x{948D}\x{948E}\x{948F}\x{9490}\x{9491}\x{9492}\x{9493}\x{9494}\x{9495}' - . '\x{9496}\x{9497}\x{9498}\x{9499}\x{949A}\x{949B}\x{949C}\x{949D}\x{949E}' - . '\x{949F}\x{94A0}\x{94A1}\x{94A2}\x{94A3}\x{94A4}\x{94A5}\x{94A6}\x{94A7}' - . '\x{94A8}\x{94A9}\x{94AA}\x{94AB}\x{94AC}\x{94AD}\x{94AE}\x{94AF}\x{94B0}' - . '\x{94B1}\x{94B2}\x{94B3}\x{94B4}\x{94B5}\x{94B6}\x{94B7}\x{94B8}\x{94B9}' - . '\x{94BA}\x{94BB}\x{94BC}\x{94BD}\x{94BE}\x{94BF}\x{94C0}\x{94C1}\x{94C2}' - . '\x{94C3}\x{94C4}\x{94C5}\x{94C6}\x{94C7}\x{94C8}\x{94C9}\x{94CA}\x{94CB}' - . '\x{94CC}\x{94CD}\x{94CE}\x{94CF}\x{94D0}\x{94D1}\x{94D2}\x{94D3}\x{94D4}' - . '\x{94D5}\x{94D6}\x{94D7}\x{94D8}\x{94D9}\x{94DA}\x{94DB}\x{94DC}\x{94DD}' - . '\x{94DE}\x{94DF}\x{94E0}\x{94E1}\x{94E2}\x{94E3}\x{94E4}\x{94E5}\x{94E6}' - . '\x{94E7}\x{94E8}\x{94E9}\x{94EA}\x{94EB}\x{94EC}\x{94ED}\x{94EE}\x{94EF}' - . '\x{94F0}\x{94F1}\x{94F2}\x{94F3}\x{94F4}\x{94F5}\x{94F6}\x{94F7}\x{94F8}' - . '\x{94F9}\x{94FA}\x{94FB}\x{94FC}\x{94FD}\x{94FE}\x{94FF}\x{9500}\x{9501}' - . '\x{9502}\x{9503}\x{9504}\x{9505}\x{9506}\x{9507}\x{9508}\x{9509}\x{950A}' - . '\x{950B}\x{950C}\x{950D}\x{950E}\x{950F}\x{9510}\x{9511}\x{9512}\x{9513}' - . '\x{9514}\x{9515}\x{9516}\x{9517}\x{9518}\x{9519}\x{951A}\x{951B}\x{951C}' - . '\x{951D}\x{951E}\x{951F}\x{9520}\x{9521}\x{9522}\x{9523}\x{9524}\x{9525}' - . '\x{9526}\x{9527}\x{9528}\x{9529}\x{952A}\x{952B}\x{952C}\x{952D}\x{952E}' - . '\x{952F}\x{9530}\x{9531}\x{9532}\x{9533}\x{9534}\x{9535}\x{9536}\x{9537}' - . '\x{9538}\x{9539}\x{953A}\x{953B}\x{953C}\x{953D}\x{953E}\x{953F}\x{9540}' - . '\x{9541}\x{9542}\x{9543}\x{9544}\x{9545}\x{9546}\x{9547}\x{9548}\x{9549}' - . '\x{954A}\x{954B}\x{954C}\x{954D}\x{954E}\x{954F}\x{9550}\x{9551}\x{9552}' - . '\x{9553}\x{9554}\x{9555}\x{9556}\x{9557}\x{9558}\x{9559}\x{955A}\x{955B}' - . '\x{955C}\x{955D}\x{955E}\x{955F}\x{9560}\x{9561}\x{9562}\x{9563}\x{9564}' - . '\x{9565}\x{9566}\x{9567}\x{9568}\x{9569}\x{956A}\x{956B}\x{956C}\x{956D}' - . '\x{956E}\x{956F}\x{9570}\x{9571}\x{9572}\x{9573}\x{9574}\x{9575}\x{9576}' - . '\x{9577}\x{957A}\x{957B}\x{957C}\x{957D}\x{957F}\x{9580}\x{9581}\x{9582}' - . '\x{9583}\x{9584}\x{9586}\x{9587}\x{9588}\x{9589}\x{958A}\x{958B}\x{958C}' - . '\x{958D}\x{958E}\x{958F}\x{9590}\x{9591}\x{9592}\x{9593}\x{9594}\x{9595}' - . '\x{9596}\x{9598}\x{9599}\x{959A}\x{959B}\x{959C}\x{959D}\x{959E}\x{959F}' - . '\x{95A1}\x{95A2}\x{95A3}\x{95A4}\x{95A5}\x{95A6}\x{95A7}\x{95A8}\x{95A9}' - . '\x{95AA}\x{95AB}\x{95AC}\x{95AD}\x{95AE}\x{95AF}\x{95B0}\x{95B1}\x{95B2}' - . '\x{95B5}\x{95B6}\x{95B7}\x{95B9}\x{95BA}\x{95BB}\x{95BC}\x{95BD}\x{95BE}' - . '\x{95BF}\x{95C0}\x{95C2}\x{95C3}\x{95C4}\x{95C5}\x{95C6}\x{95C7}\x{95C8}' - . '\x{95C9}\x{95CA}\x{95CB}\x{95CC}\x{95CD}\x{95CE}\x{95CF}\x{95D0}\x{95D1}' - . '\x{95D2}\x{95D3}\x{95D4}\x{95D5}\x{95D6}\x{95D7}\x{95D8}\x{95DA}\x{95DB}' - . '\x{95DC}\x{95DE}\x{95DF}\x{95E0}\x{95E1}\x{95E2}\x{95E3}\x{95E4}\x{95E5}' - . '\x{95E6}\x{95E7}\x{95E8}\x{95E9}\x{95EA}\x{95EB}\x{95EC}\x{95ED}\x{95EE}' - . '\x{95EF}\x{95F0}\x{95F1}\x{95F2}\x{95F3}\x{95F4}\x{95F5}\x{95F6}\x{95F7}' - . '\x{95F8}\x{95F9}\x{95FA}\x{95FB}\x{95FC}\x{95FD}\x{95FE}\x{95FF}\x{9600}' - . '\x{9601}\x{9602}\x{9603}\x{9604}\x{9605}\x{9606}\x{9607}\x{9608}\x{9609}' - . '\x{960A}\x{960B}\x{960C}\x{960D}\x{960E}\x{960F}\x{9610}\x{9611}\x{9612}' - . '\x{9613}\x{9614}\x{9615}\x{9616}\x{9617}\x{9618}\x{9619}\x{961A}\x{961B}' - . '\x{961C}\x{961D}\x{961E}\x{961F}\x{9620}\x{9621}\x{9622}\x{9623}\x{9624}' - . '\x{9627}\x{9628}\x{962A}\x{962B}\x{962C}\x{962D}\x{962E}\x{962F}\x{9630}' - . '\x{9631}\x{9632}\x{9633}\x{9634}\x{9635}\x{9636}\x{9637}\x{9638}\x{9639}' - . '\x{963A}\x{963B}\x{963C}\x{963D}\x{963F}\x{9640}\x{9641}\x{9642}\x{9643}' - . '\x{9644}\x{9645}\x{9646}\x{9647}\x{9648}\x{9649}\x{964A}\x{964B}\x{964C}' - . '\x{964D}\x{964E}\x{964F}\x{9650}\x{9651}\x{9652}\x{9653}\x{9654}\x{9655}' - . '\x{9658}\x{9659}\x{965A}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9660}' - . '\x{9661}\x{9662}\x{9663}\x{9664}\x{9666}\x{9667}\x{9668}\x{9669}\x{966A}' - . '\x{966B}\x{966C}\x{966D}\x{966E}\x{966F}\x{9670}\x{9671}\x{9672}\x{9673}' - . '\x{9674}\x{9675}\x{9676}\x{9677}\x{9678}\x{967C}\x{967D}\x{967E}\x{9680}' - . '\x{9683}\x{9684}\x{9685}\x{9686}\x{9687}\x{9688}\x{9689}\x{968A}\x{968B}' - . '\x{968D}\x{968E}\x{968F}\x{9690}\x{9691}\x{9692}\x{9693}\x{9694}\x{9695}' - . '\x{9697}\x{9698}\x{9699}\x{969B}\x{969C}\x{969E}\x{96A0}\x{96A1}\x{96A2}' - . '\x{96A3}\x{96A4}\x{96A5}\x{96A6}\x{96A7}\x{96A8}\x{96A9}\x{96AA}\x{96AC}' - . '\x{96AD}\x{96AE}\x{96B0}\x{96B1}\x{96B3}\x{96B4}\x{96B6}\x{96B7}\x{96B8}' - . '\x{96B9}\x{96BA}\x{96BB}\x{96BC}\x{96BD}\x{96BE}\x{96BF}\x{96C0}\x{96C1}' - . '\x{96C2}\x{96C3}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C8}\x{96C9}\x{96CA}' - . '\x{96CB}\x{96CC}\x{96CD}\x{96CE}\x{96CF}\x{96D0}\x{96D1}\x{96D2}\x{96D3}' - . '\x{96D4}\x{96D5}\x{96D6}\x{96D7}\x{96D8}\x{96D9}\x{96DA}\x{96DB}\x{96DC}' - . '\x{96DD}\x{96DE}\x{96DF}\x{96E0}\x{96E1}\x{96E2}\x{96E3}\x{96E5}\x{96E8}' - . '\x{96E9}\x{96EA}\x{96EB}\x{96EC}\x{96ED}\x{96EE}\x{96EF}\x{96F0}\x{96F1}' - . '\x{96F2}\x{96F3}\x{96F4}\x{96F5}\x{96F6}\x{96F7}\x{96F8}\x{96F9}\x{96FA}' - . '\x{96FB}\x{96FD}\x{96FE}\x{96FF}\x{9700}\x{9701}\x{9702}\x{9703}\x{9704}' - . '\x{9705}\x{9706}\x{9707}\x{9708}\x{9709}\x{970A}\x{970B}\x{970C}\x{970D}' - . '\x{970E}\x{970F}\x{9710}\x{9711}\x{9712}\x{9713}\x{9715}\x{9716}\x{9718}' - . '\x{9719}\x{971C}\x{971D}\x{971E}\x{971F}\x{9720}\x{9721}\x{9722}\x{9723}' - . '\x{9724}\x{9725}\x{9726}\x{9727}\x{9728}\x{9729}\x{972A}\x{972B}\x{972C}' - . '\x{972D}\x{972E}\x{972F}\x{9730}\x{9731}\x{9732}\x{9735}\x{9736}\x{9738}' - . '\x{9739}\x{973A}\x{973B}\x{973C}\x{973D}\x{973E}\x{973F}\x{9742}\x{9743}' - . '\x{9744}\x{9745}\x{9746}\x{9747}\x{9748}\x{9749}\x{974A}\x{974B}\x{974C}' - . '\x{974E}\x{974F}\x{9750}\x{9751}\x{9752}\x{9753}\x{9754}\x{9755}\x{9756}' - . '\x{9758}\x{9759}\x{975A}\x{975B}\x{975C}\x{975D}\x{975E}\x{975F}\x{9760}' - . '\x{9761}\x{9762}\x{9765}\x{9766}\x{9767}\x{9768}\x{9769}\x{976A}\x{976B}' - . '\x{976C}\x{976D}\x{976E}\x{976F}\x{9770}\x{9772}\x{9773}\x{9774}\x{9776}' - . '\x{9777}\x{9778}\x{9779}\x{977A}\x{977B}\x{977C}\x{977D}\x{977E}\x{977F}' - . '\x{9780}\x{9781}\x{9782}\x{9783}\x{9784}\x{9785}\x{9786}\x{9788}\x{978A}' - . '\x{978B}\x{978C}\x{978D}\x{978E}\x{978F}\x{9790}\x{9791}\x{9792}\x{9793}' - . '\x{9794}\x{9795}\x{9796}\x{9797}\x{9798}\x{9799}\x{979A}\x{979C}\x{979D}' - . '\x{979E}\x{979F}\x{97A0}\x{97A1}\x{97A2}\x{97A3}\x{97A4}\x{97A5}\x{97A6}' - . '\x{97A7}\x{97A8}\x{97AA}\x{97AB}\x{97AC}\x{97AD}\x{97AE}\x{97AF}\x{97B2}' - . '\x{97B3}\x{97B4}\x{97B6}\x{97B7}\x{97B8}\x{97B9}\x{97BA}\x{97BB}\x{97BC}' - . '\x{97BD}\x{97BF}\x{97C1}\x{97C2}\x{97C3}\x{97C4}\x{97C5}\x{97C6}\x{97C7}' - . '\x{97C8}\x{97C9}\x{97CA}\x{97CB}\x{97CC}\x{97CD}\x{97CE}\x{97CF}\x{97D0}' - . '\x{97D1}\x{97D3}\x{97D4}\x{97D5}\x{97D6}\x{97D7}\x{97D8}\x{97D9}\x{97DA}' - . '\x{97DB}\x{97DC}\x{97DD}\x{97DE}\x{97DF}\x{97E0}\x{97E1}\x{97E2}\x{97E3}' - . '\x{97E4}\x{97E5}\x{97E6}\x{97E7}\x{97E8}\x{97E9}\x{97EA}\x{97EB}\x{97EC}' - . '\x{97ED}\x{97EE}\x{97EF}\x{97F0}\x{97F1}\x{97F2}\x{97F3}\x{97F4}\x{97F5}' - . '\x{97F6}\x{97F7}\x{97F8}\x{97F9}\x{97FA}\x{97FB}\x{97FD}\x{97FE}\x{97FF}' - . '\x{9800}\x{9801}\x{9802}\x{9803}\x{9804}\x{9805}\x{9806}\x{9807}\x{9808}' - . '\x{9809}\x{980A}\x{980B}\x{980C}\x{980D}\x{980E}\x{980F}\x{9810}\x{9811}' - . '\x{9812}\x{9813}\x{9814}\x{9815}\x{9816}\x{9817}\x{9818}\x{9819}\x{981A}' - . '\x{981B}\x{981C}\x{981D}\x{981E}\x{9820}\x{9821}\x{9822}\x{9823}\x{9824}' - . '\x{9826}\x{9827}\x{9828}\x{9829}\x{982B}\x{982D}\x{982E}\x{982F}\x{9830}' - . '\x{9831}\x{9832}\x{9834}\x{9835}\x{9836}\x{9837}\x{9838}\x{9839}\x{983B}' - . '\x{983C}\x{983D}\x{983F}\x{9840}\x{9841}\x{9843}\x{9844}\x{9845}\x{9846}' - . '\x{9848}\x{9849}\x{984A}\x{984C}\x{984D}\x{984E}\x{984F}\x{9850}\x{9851}' - . '\x{9852}\x{9853}\x{9854}\x{9855}\x{9857}\x{9858}\x{9859}\x{985A}\x{985B}' - . '\x{985C}\x{985D}\x{985E}\x{985F}\x{9860}\x{9861}\x{9862}\x{9863}\x{9864}' - . '\x{9865}\x{9867}\x{9869}\x{986A}\x{986B}\x{986C}\x{986D}\x{986E}\x{986F}' - . '\x{9870}\x{9871}\x{9872}\x{9873}\x{9874}\x{9875}\x{9876}\x{9877}\x{9878}' - . '\x{9879}\x{987A}\x{987B}\x{987C}\x{987D}\x{987E}\x{987F}\x{9880}\x{9881}' - . '\x{9882}\x{9883}\x{9884}\x{9885}\x{9886}\x{9887}\x{9888}\x{9889}\x{988A}' - . '\x{988B}\x{988C}\x{988D}\x{988E}\x{988F}\x{9890}\x{9891}\x{9892}\x{9893}' - . '\x{9894}\x{9895}\x{9896}\x{9897}\x{9898}\x{9899}\x{989A}\x{989B}\x{989C}' - . '\x{989D}\x{989E}\x{989F}\x{98A0}\x{98A1}\x{98A2}\x{98A3}\x{98A4}\x{98A5}' - . '\x{98A6}\x{98A7}\x{98A8}\x{98A9}\x{98AA}\x{98AB}\x{98AC}\x{98AD}\x{98AE}' - . '\x{98AF}\x{98B0}\x{98B1}\x{98B2}\x{98B3}\x{98B4}\x{98B5}\x{98B6}\x{98B8}' - . '\x{98B9}\x{98BA}\x{98BB}\x{98BC}\x{98BD}\x{98BE}\x{98BF}\x{98C0}\x{98C1}' - . '\x{98C2}\x{98C3}\x{98C4}\x{98C5}\x{98C6}\x{98C8}\x{98C9}\x{98CB}\x{98CC}' - . '\x{98CD}\x{98CE}\x{98CF}\x{98D0}\x{98D1}\x{98D2}\x{98D3}\x{98D4}\x{98D5}' - . '\x{98D6}\x{98D7}\x{98D8}\x{98D9}\x{98DA}\x{98DB}\x{98DC}\x{98DD}\x{98DE}' - . '\x{98DF}\x{98E0}\x{98E2}\x{98E3}\x{98E5}\x{98E6}\x{98E7}\x{98E8}\x{98E9}' - . '\x{98EA}\x{98EB}\x{98ED}\x{98EF}\x{98F0}\x{98F2}\x{98F3}\x{98F4}\x{98F5}' - . '\x{98F6}\x{98F7}\x{98F9}\x{98FA}\x{98FC}\x{98FD}\x{98FE}\x{98FF}\x{9900}' - . '\x{9901}\x{9902}\x{9903}\x{9904}\x{9905}\x{9906}\x{9907}\x{9908}\x{9909}' - . '\x{990A}\x{990B}\x{990C}\x{990D}\x{990E}\x{990F}\x{9910}\x{9911}\x{9912}' - . '\x{9913}\x{9914}\x{9915}\x{9916}\x{9917}\x{9918}\x{991A}\x{991B}\x{991C}' - . '\x{991D}\x{991E}\x{991F}\x{9920}\x{9921}\x{9922}\x{9923}\x{9924}\x{9925}' - . '\x{9926}\x{9927}\x{9928}\x{9929}\x{992A}\x{992B}\x{992C}\x{992D}\x{992E}' - . '\x{992F}\x{9930}\x{9931}\x{9932}\x{9933}\x{9934}\x{9935}\x{9936}\x{9937}' - . '\x{9938}\x{9939}\x{993A}\x{993C}\x{993D}\x{993E}\x{993F}\x{9940}\x{9941}' - . '\x{9942}\x{9943}\x{9945}\x{9946}\x{9947}\x{9948}\x{9949}\x{994A}\x{994B}' - . '\x{994C}\x{994E}\x{994F}\x{9950}\x{9951}\x{9952}\x{9953}\x{9954}\x{9955}' - . '\x{9956}\x{9957}\x{9958}\x{9959}\x{995B}\x{995C}\x{995E}\x{995F}\x{9960}' - . '\x{9961}\x{9962}\x{9963}\x{9964}\x{9965}\x{9966}\x{9967}\x{9968}\x{9969}' - . '\x{996A}\x{996B}\x{996C}\x{996D}\x{996E}\x{996F}\x{9970}\x{9971}\x{9972}' - . '\x{9973}\x{9974}\x{9975}\x{9976}\x{9977}\x{9978}\x{9979}\x{997A}\x{997B}' - . '\x{997C}\x{997D}\x{997E}\x{997F}\x{9980}\x{9981}\x{9982}\x{9983}\x{9984}' - . '\x{9985}\x{9986}\x{9987}\x{9988}\x{9989}\x{998A}\x{998B}\x{998C}\x{998D}' - . '\x{998E}\x{998F}\x{9990}\x{9991}\x{9992}\x{9993}\x{9994}\x{9995}\x{9996}' - . '\x{9997}\x{9998}\x{9999}\x{999A}\x{999B}\x{999C}\x{999D}\x{999E}\x{999F}' - . '\x{99A0}\x{99A1}\x{99A2}\x{99A3}\x{99A4}\x{99A5}\x{99A6}\x{99A7}\x{99A8}' - . '\x{99A9}\x{99AA}\x{99AB}\x{99AC}\x{99AD}\x{99AE}\x{99AF}\x{99B0}\x{99B1}' - . '\x{99B2}\x{99B3}\x{99B4}\x{99B5}\x{99B6}\x{99B7}\x{99B8}\x{99B9}\x{99BA}' - . '\x{99BB}\x{99BC}\x{99BD}\x{99BE}\x{99C0}\x{99C1}\x{99C2}\x{99C3}\x{99C4}' - . '\x{99C6}\x{99C7}\x{99C8}\x{99C9}\x{99CA}\x{99CB}\x{99CC}\x{99CD}\x{99CE}' - . '\x{99CF}\x{99D0}\x{99D1}\x{99D2}\x{99D3}\x{99D4}\x{99D5}\x{99D6}\x{99D7}' - . '\x{99D8}\x{99D9}\x{99DA}\x{99DB}\x{99DC}\x{99DD}\x{99DE}\x{99DF}\x{99E1}' - . '\x{99E2}\x{99E3}\x{99E4}\x{99E5}\x{99E7}\x{99E8}\x{99E9}\x{99EA}\x{99EC}' - . '\x{99ED}\x{99EE}\x{99EF}\x{99F0}\x{99F1}\x{99F2}\x{99F3}\x{99F4}\x{99F6}' - . '\x{99F7}\x{99F8}\x{99F9}\x{99FA}\x{99FB}\x{99FC}\x{99FD}\x{99FE}\x{99FF}' - . '\x{9A00}\x{9A01}\x{9A02}\x{9A03}\x{9A04}\x{9A05}\x{9A06}\x{9A07}\x{9A08}' - . '\x{9A09}\x{9A0A}\x{9A0B}\x{9A0C}\x{9A0D}\x{9A0E}\x{9A0F}\x{9A11}\x{9A14}' - . '\x{9A15}\x{9A16}\x{9A19}\x{9A1A}\x{9A1B}\x{9A1C}\x{9A1D}\x{9A1E}\x{9A1F}' - . '\x{9A20}\x{9A21}\x{9A22}\x{9A23}\x{9A24}\x{9A25}\x{9A26}\x{9A27}\x{9A29}' - . '\x{9A2A}\x{9A2B}\x{9A2C}\x{9A2D}\x{9A2E}\x{9A2F}\x{9A30}\x{9A31}\x{9A32}' - . '\x{9A33}\x{9A34}\x{9A35}\x{9A36}\x{9A37}\x{9A38}\x{9A39}\x{9A3A}\x{9A3C}' - . '\x{9A3D}\x{9A3E}\x{9A3F}\x{9A40}\x{9A41}\x{9A42}\x{9A43}\x{9A44}\x{9A45}' - . '\x{9A46}\x{9A47}\x{9A48}\x{9A49}\x{9A4A}\x{9A4B}\x{9A4C}\x{9A4D}\x{9A4E}' - . '\x{9A4F}\x{9A50}\x{9A52}\x{9A53}\x{9A54}\x{9A55}\x{9A56}\x{9A57}\x{9A59}' - . '\x{9A5A}\x{9A5B}\x{9A5C}\x{9A5E}\x{9A5F}\x{9A60}\x{9A61}\x{9A62}\x{9A64}' - . '\x{9A65}\x{9A66}\x{9A67}\x{9A68}\x{9A69}\x{9A6A}\x{9A6B}\x{9A6C}\x{9A6D}' - . '\x{9A6E}\x{9A6F}\x{9A70}\x{9A71}\x{9A72}\x{9A73}\x{9A74}\x{9A75}\x{9A76}' - . '\x{9A77}\x{9A78}\x{9A79}\x{9A7A}\x{9A7B}\x{9A7C}\x{9A7D}\x{9A7E}\x{9A7F}' - . '\x{9A80}\x{9A81}\x{9A82}\x{9A83}\x{9A84}\x{9A85}\x{9A86}\x{9A87}\x{9A88}' - . '\x{9A89}\x{9A8A}\x{9A8B}\x{9A8C}\x{9A8D}\x{9A8E}\x{9A8F}\x{9A90}\x{9A91}' - . '\x{9A92}\x{9A93}\x{9A94}\x{9A95}\x{9A96}\x{9A97}\x{9A98}\x{9A99}\x{9A9A}' - . '\x{9A9B}\x{9A9C}\x{9A9D}\x{9A9E}\x{9A9F}\x{9AA0}\x{9AA1}\x{9AA2}\x{9AA3}' - . '\x{9AA4}\x{9AA5}\x{9AA6}\x{9AA7}\x{9AA8}\x{9AAA}\x{9AAB}\x{9AAC}\x{9AAD}' - . '\x{9AAE}\x{9AAF}\x{9AB0}\x{9AB1}\x{9AB2}\x{9AB3}\x{9AB4}\x{9AB5}\x{9AB6}' - . '\x{9AB7}\x{9AB8}\x{9AB9}\x{9ABA}\x{9ABB}\x{9ABC}\x{9ABE}\x{9ABF}\x{9AC0}' - . '\x{9AC1}\x{9AC2}\x{9AC3}\x{9AC4}\x{9AC5}\x{9AC6}\x{9AC7}\x{9AC9}\x{9ACA}' - . '\x{9ACB}\x{9ACC}\x{9ACD}\x{9ACE}\x{9ACF}\x{9AD0}\x{9AD1}\x{9AD2}\x{9AD3}' - . '\x{9AD4}\x{9AD5}\x{9AD6}\x{9AD8}\x{9AD9}\x{9ADA}\x{9ADB}\x{9ADC}\x{9ADD}' - . '\x{9ADE}\x{9ADF}\x{9AE1}\x{9AE2}\x{9AE3}\x{9AE5}\x{9AE6}\x{9AE7}\x{9AEA}' - . '\x{9AEB}\x{9AEC}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF2}\x{9AF3}\x{9AF4}' - . '\x{9AF5}\x{9AF6}\x{9AF7}\x{9AF8}\x{9AF9}\x{9AFA}\x{9AFB}\x{9AFC}\x{9AFD}' - . '\x{9AFE}\x{9AFF}\x{9B01}\x{9B03}\x{9B04}\x{9B05}\x{9B06}\x{9B07}\x{9B08}' - . '\x{9B0A}\x{9B0B}\x{9B0C}\x{9B0D}\x{9B0E}\x{9B0F}\x{9B10}\x{9B11}\x{9B12}' - . '\x{9B13}\x{9B15}\x{9B16}\x{9B17}\x{9B18}\x{9B19}\x{9B1A}\x{9B1C}\x{9B1D}' - . '\x{9B1E}\x{9B1F}\x{9B20}\x{9B21}\x{9B22}\x{9B23}\x{9B24}\x{9B25}\x{9B26}' - . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2B}\x{9B2C}\x{9B2D}\x{9B2E}\x{9B2F}' - . '\x{9B30}\x{9B31}\x{9B32}\x{9B33}\x{9B35}\x{9B36}\x{9B37}\x{9B38}\x{9B39}' - . '\x{9B3A}\x{9B3B}\x{9B3C}\x{9B3E}\x{9B3F}\x{9B41}\x{9B42}\x{9B43}\x{9B44}' - . '\x{9B45}\x{9B46}\x{9B47}\x{9B48}\x{9B49}\x{9B4A}\x{9B4B}\x{9B4C}\x{9B4D}' - . '\x{9B4E}\x{9B4F}\x{9B51}\x{9B52}\x{9B53}\x{9B54}\x{9B55}\x{9B56}\x{9B58}' - . '\x{9B59}\x{9B5A}\x{9B5B}\x{9B5C}\x{9B5D}\x{9B5E}\x{9B5F}\x{9B60}\x{9B61}' - . '\x{9B63}\x{9B64}\x{9B65}\x{9B66}\x{9B67}\x{9B68}\x{9B69}\x{9B6A}\x{9B6B}' - . '\x{9B6C}\x{9B6D}\x{9B6E}\x{9B6F}\x{9B70}\x{9B71}\x{9B73}\x{9B74}\x{9B75}' - . '\x{9B76}\x{9B77}\x{9B78}\x{9B79}\x{9B7A}\x{9B7B}\x{9B7C}\x{9B7D}\x{9B7E}' - . '\x{9B7F}\x{9B80}\x{9B81}\x{9B82}\x{9B83}\x{9B84}\x{9B85}\x{9B86}\x{9B87}' - . '\x{9B88}\x{9B8A}\x{9B8B}\x{9B8D}\x{9B8E}\x{9B8F}\x{9B90}\x{9B91}\x{9B92}' - . '\x{9B93}\x{9B94}\x{9B95}\x{9B96}\x{9B97}\x{9B98}\x{9B9A}\x{9B9B}\x{9B9C}' - . '\x{9B9D}\x{9B9E}\x{9B9F}\x{9BA0}\x{9BA1}\x{9BA2}\x{9BA3}\x{9BA4}\x{9BA5}' - . '\x{9BA6}\x{9BA7}\x{9BA8}\x{9BA9}\x{9BAA}\x{9BAB}\x{9BAC}\x{9BAD}\x{9BAE}' - . '\x{9BAF}\x{9BB0}\x{9BB1}\x{9BB2}\x{9BB3}\x{9BB4}\x{9BB5}\x{9BB6}\x{9BB7}' - . '\x{9BB8}\x{9BB9}\x{9BBA}\x{9BBB}\x{9BBC}\x{9BBD}\x{9BBE}\x{9BBF}\x{9BC0}' - . '\x{9BC1}\x{9BC3}\x{9BC4}\x{9BC5}\x{9BC6}\x{9BC7}\x{9BC8}\x{9BC9}\x{9BCA}' - . '\x{9BCB}\x{9BCC}\x{9BCD}\x{9BCE}\x{9BCF}\x{9BD0}\x{9BD1}\x{9BD2}\x{9BD3}' - . '\x{9BD4}\x{9BD5}\x{9BD6}\x{9BD7}\x{9BD8}\x{9BD9}\x{9BDA}\x{9BDB}\x{9BDC}' - . '\x{9BDD}\x{9BDE}\x{9BDF}\x{9BE0}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}\x{9BE5}' - . '\x{9BE6}\x{9BE7}\x{9BE8}\x{9BE9}\x{9BEA}\x{9BEB}\x{9BEC}\x{9BED}\x{9BEE}' - . '\x{9BEF}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF3}\x{9BF4}\x{9BF5}\x{9BF7}\x{9BF8}' - . '\x{9BF9}\x{9BFA}\x{9BFB}\x{9BFC}\x{9BFD}\x{9BFE}\x{9BFF}\x{9C02}\x{9C05}' - . '\x{9C06}\x{9C07}\x{9C08}\x{9C09}\x{9C0A}\x{9C0B}\x{9C0C}\x{9C0D}\x{9C0E}' - . '\x{9C0F}\x{9C10}\x{9C11}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C16}\x{9C17}' - . '\x{9C18}\x{9C19}\x{9C1A}\x{9C1B}\x{9C1C}\x{9C1D}\x{9C1E}\x{9C1F}\x{9C20}' - . '\x{9C21}\x{9C22}\x{9C23}\x{9C24}\x{9C25}\x{9C26}\x{9C27}\x{9C28}\x{9C29}' - . '\x{9C2A}\x{9C2B}\x{9C2C}\x{9C2D}\x{9C2F}\x{9C30}\x{9C31}\x{9C32}\x{9C33}' - . '\x{9C34}\x{9C35}\x{9C36}\x{9C37}\x{9C38}\x{9C39}\x{9C3A}\x{9C3B}\x{9C3C}' - . '\x{9C3D}\x{9C3E}\x{9C3F}\x{9C40}\x{9C41}\x{9C43}\x{9C44}\x{9C45}\x{9C46}' - . '\x{9C47}\x{9C48}\x{9C49}\x{9C4A}\x{9C4B}\x{9C4C}\x{9C4D}\x{9C4E}\x{9C50}' - . '\x{9C52}\x{9C53}\x{9C54}\x{9C55}\x{9C56}\x{9C57}\x{9C58}\x{9C59}\x{9C5A}' - . '\x{9C5B}\x{9C5C}\x{9C5D}\x{9C5E}\x{9C5F}\x{9C60}\x{9C62}\x{9C63}\x{9C65}' - . '\x{9C66}\x{9C67}\x{9C68}\x{9C69}\x{9C6A}\x{9C6B}\x{9C6C}\x{9C6D}\x{9C6E}' - . '\x{9C6F}\x{9C70}\x{9C71}\x{9C72}\x{9C73}\x{9C74}\x{9C75}\x{9C77}\x{9C78}' - . '\x{9C79}\x{9C7A}\x{9C7C}\x{9C7D}\x{9C7E}\x{9C7F}\x{9C80}\x{9C81}\x{9C82}' - . '\x{9C83}\x{9C84}\x{9C85}\x{9C86}\x{9C87}\x{9C88}\x{9C89}\x{9C8A}\x{9C8B}' - . '\x{9C8C}\x{9C8D}\x{9C8E}\x{9C8F}\x{9C90}\x{9C91}\x{9C92}\x{9C93}\x{9C94}' - . '\x{9C95}\x{9C96}\x{9C97}\x{9C98}\x{9C99}\x{9C9A}\x{9C9B}\x{9C9C}\x{9C9D}' - . '\x{9C9E}\x{9C9F}\x{9CA0}\x{9CA1}\x{9CA2}\x{9CA3}\x{9CA4}\x{9CA5}\x{9CA6}' - . '\x{9CA7}\x{9CA8}\x{9CA9}\x{9CAA}\x{9CAB}\x{9CAC}\x{9CAD}\x{9CAE}\x{9CAF}' - . '\x{9CB0}\x{9CB1}\x{9CB2}\x{9CB3}\x{9CB4}\x{9CB5}\x{9CB6}\x{9CB7}\x{9CB8}' - . '\x{9CB9}\x{9CBA}\x{9CBB}\x{9CBC}\x{9CBD}\x{9CBE}\x{9CBF}\x{9CC0}\x{9CC1}' - . '\x{9CC2}\x{9CC3}\x{9CC4}\x{9CC5}\x{9CC6}\x{9CC7}\x{9CC8}\x{9CC9}\x{9CCA}' - . '\x{9CCB}\x{9CCC}\x{9CCD}\x{9CCE}\x{9CCF}\x{9CD0}\x{9CD1}\x{9CD2}\x{9CD3}' - . '\x{9CD4}\x{9CD5}\x{9CD6}\x{9CD7}\x{9CD8}\x{9CD9}\x{9CDA}\x{9CDB}\x{9CDC}' - . '\x{9CDD}\x{9CDE}\x{9CDF}\x{9CE0}\x{9CE1}\x{9CE2}\x{9CE3}\x{9CE4}\x{9CE5}' - . '\x{9CE6}\x{9CE7}\x{9CE8}\x{9CE9}\x{9CEA}\x{9CEB}\x{9CEC}\x{9CED}\x{9CEE}' - . '\x{9CEF}\x{9CF0}\x{9CF1}\x{9CF2}\x{9CF3}\x{9CF4}\x{9CF5}\x{9CF6}\x{9CF7}' - . '\x{9CF8}\x{9CF9}\x{9CFA}\x{9CFB}\x{9CFC}\x{9CFD}\x{9CFE}\x{9CFF}\x{9D00}' - . '\x{9D01}\x{9D02}\x{9D03}\x{9D04}\x{9D05}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' - . '\x{9D0A}\x{9D0B}\x{9D0F}\x{9D10}\x{9D12}\x{9D13}\x{9D14}\x{9D15}\x{9D16}' - . '\x{9D17}\x{9D18}\x{9D19}\x{9D1A}\x{9D1B}\x{9D1C}\x{9D1D}\x{9D1E}\x{9D1F}' - . '\x{9D20}\x{9D21}\x{9D22}\x{9D23}\x{9D24}\x{9D25}\x{9D26}\x{9D28}\x{9D29}' - . '\x{9D2B}\x{9D2D}\x{9D2E}\x{9D2F}\x{9D30}\x{9D31}\x{9D32}\x{9D33}\x{9D34}' - . '\x{9D36}\x{9D37}\x{9D38}\x{9D39}\x{9D3A}\x{9D3B}\x{9D3D}\x{9D3E}\x{9D3F}' - . '\x{9D40}\x{9D41}\x{9D42}\x{9D43}\x{9D45}\x{9D46}\x{9D47}\x{9D48}\x{9D49}' - . '\x{9D4A}\x{9D4B}\x{9D4C}\x{9D4D}\x{9D4E}\x{9D4F}\x{9D50}\x{9D51}\x{9D52}' - . '\x{9D53}\x{9D54}\x{9D55}\x{9D56}\x{9D57}\x{9D58}\x{9D59}\x{9D5A}\x{9D5B}' - . '\x{9D5C}\x{9D5D}\x{9D5E}\x{9D5F}\x{9D60}\x{9D61}\x{9D62}\x{9D63}\x{9D64}' - . '\x{9D65}\x{9D66}\x{9D67}\x{9D68}\x{9D69}\x{9D6A}\x{9D6B}\x{9D6C}\x{9D6E}' - . '\x{9D6F}\x{9D70}\x{9D71}\x{9D72}\x{9D73}\x{9D74}\x{9D75}\x{9D76}\x{9D77}' - . '\x{9D78}\x{9D79}\x{9D7A}\x{9D7B}\x{9D7C}\x{9D7D}\x{9D7E}\x{9D7F}\x{9D80}' - . '\x{9D81}\x{9D82}\x{9D83}\x{9D84}\x{9D85}\x{9D86}\x{9D87}\x{9D88}\x{9D89}' - . '\x{9D8A}\x{9D8B}\x{9D8C}\x{9D8D}\x{9D8E}\x{9D90}\x{9D91}\x{9D92}\x{9D93}' - . '\x{9D94}\x{9D96}\x{9D97}\x{9D98}\x{9D99}\x{9D9A}\x{9D9B}\x{9D9C}\x{9D9D}' - . '\x{9D9E}\x{9D9F}\x{9DA0}\x{9DA1}\x{9DA2}\x{9DA3}\x{9DA4}\x{9DA5}\x{9DA6}' - . '\x{9DA7}\x{9DA8}\x{9DA9}\x{9DAA}\x{9DAB}\x{9DAC}\x{9DAD}\x{9DAF}\x{9DB0}' - . '\x{9DB1}\x{9DB2}\x{9DB3}\x{9DB4}\x{9DB5}\x{9DB6}\x{9DB7}\x{9DB8}\x{9DB9}' - . '\x{9DBA}\x{9DBB}\x{9DBC}\x{9DBE}\x{9DBF}\x{9DC1}\x{9DC2}\x{9DC3}\x{9DC4}' - . '\x{9DC5}\x{9DC7}\x{9DC8}\x{9DC9}\x{9DCA}\x{9DCB}\x{9DCC}\x{9DCD}\x{9DCE}' - . '\x{9DCF}\x{9DD0}\x{9DD1}\x{9DD2}\x{9DD3}\x{9DD4}\x{9DD5}\x{9DD6}\x{9DD7}' - . '\x{9DD8}\x{9DD9}\x{9DDA}\x{9DDB}\x{9DDC}\x{9DDD}\x{9DDE}\x{9DDF}\x{9DE0}' - . '\x{9DE1}\x{9DE2}\x{9DE3}\x{9DE4}\x{9DE5}\x{9DE6}\x{9DE7}\x{9DE8}\x{9DE9}' - . '\x{9DEB}\x{9DEC}\x{9DED}\x{9DEE}\x{9DEF}\x{9DF0}\x{9DF1}\x{9DF2}\x{9DF3}' - . '\x{9DF4}\x{9DF5}\x{9DF6}\x{9DF7}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFB}\x{9DFD}' - . '\x{9DFE}\x{9DFF}\x{9E00}\x{9E01}\x{9E02}\x{9E03}\x{9E04}\x{9E05}\x{9E06}' - . '\x{9E07}\x{9E08}\x{9E09}\x{9E0A}\x{9E0B}\x{9E0C}\x{9E0D}\x{9E0F}\x{9E10}' - . '\x{9E11}\x{9E12}\x{9E13}\x{9E14}\x{9E15}\x{9E17}\x{9E18}\x{9E19}\x{9E1A}' - . '\x{9E1B}\x{9E1D}\x{9E1E}\x{9E1F}\x{9E20}\x{9E21}\x{9E22}\x{9E23}\x{9E24}' - . '\x{9E25}\x{9E26}\x{9E27}\x{9E28}\x{9E29}\x{9E2A}\x{9E2B}\x{9E2C}\x{9E2D}' - . '\x{9E2E}\x{9E2F}\x{9E30}\x{9E31}\x{9E32}\x{9E33}\x{9E34}\x{9E35}\x{9E36}' - . '\x{9E37}\x{9E38}\x{9E39}\x{9E3A}\x{9E3B}\x{9E3C}\x{9E3D}\x{9E3E}\x{9E3F}' - . '\x{9E40}\x{9E41}\x{9E42}\x{9E43}\x{9E44}\x{9E45}\x{9E46}\x{9E47}\x{9E48}' - . '\x{9E49}\x{9E4A}\x{9E4B}\x{9E4C}\x{9E4D}\x{9E4E}\x{9E4F}\x{9E50}\x{9E51}' - . '\x{9E52}\x{9E53}\x{9E54}\x{9E55}\x{9E56}\x{9E57}\x{9E58}\x{9E59}\x{9E5A}' - . '\x{9E5B}\x{9E5C}\x{9E5D}\x{9E5E}\x{9E5F}\x{9E60}\x{9E61}\x{9E62}\x{9E63}' - . '\x{9E64}\x{9E65}\x{9E66}\x{9E67}\x{9E68}\x{9E69}\x{9E6A}\x{9E6B}\x{9E6C}' - . '\x{9E6D}\x{9E6E}\x{9E6F}\x{9E70}\x{9E71}\x{9E72}\x{9E73}\x{9E74}\x{9E75}' - . '\x{9E76}\x{9E77}\x{9E79}\x{9E7A}\x{9E7C}\x{9E7D}\x{9E7E}\x{9E7F}\x{9E80}' - . '\x{9E81}\x{9E82}\x{9E83}\x{9E84}\x{9E85}\x{9E86}\x{9E87}\x{9E88}\x{9E89}' - . '\x{9E8A}\x{9E8B}\x{9E8C}\x{9E8D}\x{9E8E}\x{9E91}\x{9E92}\x{9E93}\x{9E94}' - . '\x{9E96}\x{9E97}\x{9E99}\x{9E9A}\x{9E9B}\x{9E9C}\x{9E9D}\x{9E9F}\x{9EA0}' - . '\x{9EA1}\x{9EA3}\x{9EA4}\x{9EA5}\x{9EA6}\x{9EA7}\x{9EA8}\x{9EA9}\x{9EAA}' - . '\x{9EAD}\x{9EAE}\x{9EAF}\x{9EB0}\x{9EB2}\x{9EB3}\x{9EB4}\x{9EB5}\x{9EB6}' - . '\x{9EB7}\x{9EB8}\x{9EBB}\x{9EBC}\x{9EBD}\x{9EBE}\x{9EBF}\x{9EC0}\x{9EC1}' - . '\x{9EC2}\x{9EC3}\x{9EC4}\x{9EC5}\x{9EC6}\x{9EC7}\x{9EC8}\x{9EC9}\x{9ECA}' - . '\x{9ECB}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED1}\x{9ED2}\x{9ED3}' - . '\x{9ED4}\x{9ED5}\x{9ED6}\x{9ED7}\x{9ED8}\x{9ED9}\x{9EDA}\x{9EDB}\x{9EDC}' - . '\x{9EDD}\x{9EDE}\x{9EDF}\x{9EE0}\x{9EE1}\x{9EE2}\x{9EE3}\x{9EE4}\x{9EE5}' - . '\x{9EE6}\x{9EE7}\x{9EE8}\x{9EE9}\x{9EEA}\x{9EEB}\x{9EED}\x{9EEE}\x{9EEF}' - . '\x{9EF0}\x{9EF2}\x{9EF3}\x{9EF4}\x{9EF5}\x{9EF6}\x{9EF7}\x{9EF8}\x{9EF9}' - . '\x{9EFA}\x{9EFB}\x{9EFC}\x{9EFD}\x{9EFE}\x{9EFF}\x{9F00}\x{9F01}\x{9F02}' - . '\x{9F04}\x{9F05}\x{9F06}\x{9F07}\x{9F08}\x{9F09}\x{9F0A}\x{9F0B}\x{9F0C}' - . '\x{9F0D}\x{9F0E}\x{9F0F}\x{9F10}\x{9F12}\x{9F13}\x{9F15}\x{9F16}\x{9F17}' - . '\x{9F18}\x{9F19}\x{9F1A}\x{9F1B}\x{9F1C}\x{9F1D}\x{9F1E}\x{9F1F}\x{9F20}' - . '\x{9F22}\x{9F23}\x{9F24}\x{9F25}\x{9F27}\x{9F28}\x{9F29}\x{9F2A}\x{9F2B}' - . '\x{9F2C}\x{9F2D}\x{9F2E}\x{9F2F}\x{9F30}\x{9F31}\x{9F32}\x{9F33}\x{9F34}' - . '\x{9F35}\x{9F36}\x{9F37}\x{9F38}\x{9F39}\x{9F3A}\x{9F3B}\x{9F3C}\x{9F3D}' - . '\x{9F3E}\x{9F3F}\x{9F40}\x{9F41}\x{9F42}\x{9F43}\x{9F44}\x{9F46}\x{9F47}' - . '\x{9F48}\x{9F49}\x{9F4A}\x{9F4B}\x{9F4C}\x{9F4D}\x{9F4E}\x{9F4F}\x{9F50}' - . '\x{9F51}\x{9F52}\x{9F54}\x{9F55}\x{9F56}\x{9F57}\x{9F58}\x{9F59}\x{9F5A}' - . '\x{9F5B}\x{9F5C}\x{9F5D}\x{9F5E}\x{9F5F}\x{9F60}\x{9F61}\x{9F63}\x{9F64}' - . '\x{9F65}\x{9F66}\x{9F67}\x{9F68}\x{9F69}\x{9F6A}\x{9F6B}\x{9F6C}\x{9F6E}' - . '\x{9F6F}\x{9F70}\x{9F71}\x{9F72}\x{9F73}\x{9F74}\x{9F75}\x{9F76}\x{9F77}' - . '\x{9F78}\x{9F79}\x{9F7A}\x{9F7B}\x{9F7C}\x{9F7D}\x{9F7E}\x{9F7F}\x{9F80}' - . '\x{9F81}\x{9F82}\x{9F83}\x{9F84}\x{9F85}\x{9F86}\x{9F87}\x{9F88}\x{9F89}' - . '\x{9F8A}\x{9F8B}\x{9F8C}\x{9F8D}\x{9F8E}\x{9F8F}\x{9F90}\x{9F91}\x{9F92}' - . '\x{9F93}\x{9F94}\x{9F95}\x{9F96}\x{9F97}\x{9F98}\x{9F99}\x{9F9A}\x{9F9B}' - . '\x{9F9C}\x{9F9D}\x{9F9E}\x{9F9F}\x{9FA0}\x{9FA2}\x{9FA4}\x{9FA5}]{1,20}$/iu', -]; diff --git a/lib/laminas/laminas-validator/src/Hostname/Cn.php b/lib/laminas/laminas-validator/src/Hostname/Cn.php deleted file mode 100644 index d280764b0..000000000 --- a/lib/laminas/laminas-validator/src/Hostname/Cn.php +++ /dev/null @@ -1,2179 +0,0 @@ - '/^[\x{002d}0-9a-z\x{3447}\x{3473}\x{359E}\x{360E}\x{361A}\x{3918}\x{396E}\x{39CF}\x{39D0}' - . '\x{39DF}\x{3A73}\x{3B4E}\x{3C6E}\x{3CE0}\x{4056}\x{415F}\x{4337}\x{43AC}' - . '\x{43B1}\x{43DD}\x{44D6}\x{464C}\x{4661}\x{4723}\x{4729}\x{477C}\x{478D}' - . '\x{4947}\x{497A}\x{497D}\x{4982}\x{4983}\x{4985}\x{4986}\x{499B}\x{499F}' - . '\x{49B6}\x{49B7}\x{4C77}\x{4C9F}\x{4CA0}\x{4CA1}\x{4CA2}\x{4CA3}\x{4D13}' - . '\x{4D14}\x{4D15}\x{4D16}\x{4D17}\x{4D18}\x{4D19}\x{4DAE}\x{4E00}\x{4E01}' - . '\x{4E02}\x{4E03}\x{4E04}\x{4E05}\x{4E06}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' - . '\x{4E0B}\x{4E0C}\x{4E0D}\x{4E0E}\x{4E0F}\x{4E10}\x{4E11}\x{4E13}\x{4E14}' - . '\x{4E15}\x{4E16}\x{4E17}\x{4E18}\x{4E19}\x{4E1A}\x{4E1B}\x{4E1C}\x{4E1D}' - . '\x{4E1E}\x{4E1F}\x{4E20}\x{4E21}\x{4E22}\x{4E23}\x{4E24}\x{4E25}\x{4E26}' - . '\x{4E27}\x{4E28}\x{4E2A}\x{4E2B}\x{4E2C}\x{4E2D}\x{4E2E}\x{4E2F}\x{4E30}' - . '\x{4E31}\x{4E32}\x{4E33}\x{4E34}\x{4E35}\x{4E36}\x{4E37}\x{4E38}\x{4E39}' - . '\x{4E3A}\x{4E3B}\x{4E3C}\x{4E3D}\x{4E3E}\x{4E3F}\x{4E40}\x{4E41}\x{4E42}' - . '\x{4E43}\x{4E44}\x{4E45}\x{4E46}\x{4E47}\x{4E48}\x{4E49}\x{4E4A}\x{4E4B}' - . '\x{4E4C}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E50}\x{4E51}\x{4E52}\x{4E53}\x{4E54}' - . '\x{4E56}\x{4E57}\x{4E58}\x{4E59}\x{4E5A}\x{4E5B}\x{4E5C}\x{4E5D}\x{4E5E}' - . '\x{4E5F}\x{4E60}\x{4E61}\x{4E62}\x{4E63}\x{4E64}\x{4E65}\x{4E66}\x{4E67}' - . '\x{4E69}\x{4E6A}\x{4E6B}\x{4E6C}\x{4E6D}\x{4E6E}\x{4E6F}\x{4E70}\x{4E71}' - . '\x{4E72}\x{4E73}\x{4E74}\x{4E75}\x{4E76}\x{4E77}\x{4E78}\x{4E7A}\x{4E7B}' - . '\x{4E7C}\x{4E7D}\x{4E7E}\x{4E7F}\x{4E80}\x{4E81}\x{4E82}\x{4E83}\x{4E84}' - . '\x{4E85}\x{4E86}\x{4E87}\x{4E88}\x{4E89}\x{4E8B}\x{4E8C}\x{4E8D}\x{4E8E}' - . '\x{4E8F}\x{4E90}\x{4E91}\x{4E92}\x{4E93}\x{4E94}\x{4E95}\x{4E97}\x{4E98}' - . '\x{4E99}\x{4E9A}\x{4E9B}\x{4E9C}\x{4E9D}\x{4E9E}\x{4E9F}\x{4EA0}\x{4EA1}' - . '\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA7}\x{4EA8}\x{4EA9}\x{4EAA}\x{4EAB}' - . '\x{4EAC}\x{4EAD}\x{4EAE}\x{4EAF}\x{4EB0}\x{4EB1}\x{4EB2}\x{4EB3}\x{4EB4}' - . '\x{4EB5}\x{4EB6}\x{4EB7}\x{4EB8}\x{4EB9}\x{4EBA}\x{4EBB}\x{4EBD}\x{4EBE}' - . '\x{4EBF}\x{4EC0}\x{4EC1}\x{4EC2}\x{4EC3}\x{4EC4}\x{4EC5}\x{4EC6}\x{4EC7}' - . '\x{4EC8}\x{4EC9}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED0}\x{4ED1}' - . '\x{4ED2}\x{4ED3}\x{4ED4}\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDA}' - . '\x{4EDB}\x{4EDC}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE0}\x{4EE1}\x{4EE2}\x{4EE3}' - . '\x{4EE4}\x{4EE5}\x{4EE6}\x{4EE8}\x{4EE9}\x{4EEA}\x{4EEB}\x{4EEC}\x{4EEF}' - . '\x{4EF0}\x{4EF1}\x{4EF2}\x{4EF3}\x{4EF4}\x{4EF5}\x{4EF6}\x{4EF7}\x{4EFB}' - . '\x{4EFD}\x{4EFF}\x{4F00}\x{4F01}\x{4F02}\x{4F03}\x{4F04}\x{4F05}\x{4F06}' - . '\x{4F08}\x{4F09}\x{4F0A}\x{4F0B}\x{4F0C}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}' - . '\x{4F11}\x{4F12}\x{4F13}\x{4F14}\x{4F15}\x{4F17}\x{4F18}\x{4F19}\x{4F1A}' - . '\x{4F1B}\x{4F1C}\x{4F1D}\x{4F1E}\x{4F1F}\x{4F20}\x{4F21}\x{4F22}\x{4F23}' - . '\x{4F24}\x{4F25}\x{4F26}\x{4F27}\x{4F29}\x{4F2A}\x{4F2B}\x{4F2C}\x{4F2D}' - . '\x{4F2E}\x{4F2F}\x{4F30}\x{4F32}\x{4F33}\x{4F34}\x{4F36}\x{4F38}\x{4F39}' - . '\x{4F3A}\x{4F3B}\x{4F3C}\x{4F3D}\x{4F3E}\x{4F3F}\x{4F41}\x{4F42}\x{4F43}' - . '\x{4F45}\x{4F46}\x{4F47}\x{4F48}\x{4F49}\x{4F4A}\x{4F4B}\x{4F4C}\x{4F4D}' - . '\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}\x{4F52}\x{4F53}\x{4F54}\x{4F55}\x{4F56}' - . '\x{4F57}\x{4F58}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}\x{4F5F}' - . '\x{4F60}\x{4F61}\x{4F62}\x{4F63}\x{4F64}\x{4F65}\x{4F66}\x{4F67}\x{4F68}' - . '\x{4F69}\x{4F6A}\x{4F6B}\x{4F6C}\x{4F6D}\x{4F6E}\x{4F6F}\x{4F70}\x{4F72}' - . '\x{4F73}\x{4F74}\x{4F75}\x{4F76}\x{4F77}\x{4F78}\x{4F79}\x{4F7A}\x{4F7B}' - . '\x{4F7C}\x{4F7D}\x{4F7E}\x{4F7F}\x{4F80}\x{4F81}\x{4F82}\x{4F83}\x{4F84}' - . '\x{4F85}\x{4F86}\x{4F87}\x{4F88}\x{4F89}\x{4F8A}\x{4F8B}\x{4F8D}\x{4F8F}' - . '\x{4F90}\x{4F91}\x{4F92}\x{4F93}\x{4F94}\x{4F95}\x{4F96}\x{4F97}\x{4F98}' - . '\x{4F99}\x{4F9A}\x{4F9B}\x{4F9C}\x{4F9D}\x{4F9E}\x{4F9F}\x{4FA0}\x{4FA1}' - . '\x{4FA3}\x{4FA4}\x{4FA5}\x{4FA6}\x{4FA7}\x{4FA8}\x{4FA9}\x{4FAA}\x{4FAB}' - . '\x{4FAC}\x{4FAE}\x{4FAF}\x{4FB0}\x{4FB1}\x{4FB2}\x{4FB3}\x{4FB4}\x{4FB5}' - . '\x{4FB6}\x{4FB7}\x{4FB8}\x{4FB9}\x{4FBA}\x{4FBB}\x{4FBC}\x{4FBE}\x{4FBF}' - . '\x{4FC0}\x{4FC1}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FC5}\x{4FC7}\x{4FC9}\x{4FCA}' - . '\x{4FCB}\x{4FCD}\x{4FCE}\x{4FCF}\x{4FD0}\x{4FD1}\x{4FD2}\x{4FD3}\x{4FD4}' - . '\x{4FD5}\x{4FD6}\x{4FD7}\x{4FD8}\x{4FD9}\x{4FDA}\x{4FDB}\x{4FDC}\x{4FDD}' - . '\x{4FDE}\x{4FDF}\x{4FE0}\x{4FE1}\x{4FE3}\x{4FE4}\x{4FE5}\x{4FE6}\x{4FE7}' - . '\x{4FE8}\x{4FE9}\x{4FEA}\x{4FEB}\x{4FEC}\x{4FED}\x{4FEE}\x{4FEF}\x{4FF0}' - . '\x{4FF1}\x{4FF2}\x{4FF3}\x{4FF4}\x{4FF5}\x{4FF6}\x{4FF7}\x{4FF8}\x{4FF9}' - . '\x{4FFA}\x{4FFB}\x{4FFE}\x{4FFF}\x{5000}\x{5001}\x{5002}\x{5003}\x{5004}' - . '\x{5005}\x{5006}\x{5007}\x{5008}\x{5009}\x{500A}\x{500B}\x{500C}\x{500D}' - . '\x{500E}\x{500F}\x{5011}\x{5012}\x{5013}\x{5014}\x{5015}\x{5016}\x{5017}' - . '\x{5018}\x{5019}\x{501A}\x{501B}\x{501C}\x{501D}\x{501E}\x{501F}\x{5020}' - . '\x{5021}\x{5022}\x{5023}\x{5024}\x{5025}\x{5026}\x{5027}\x{5028}\x{5029}' - . '\x{502A}\x{502B}\x{502C}\x{502D}\x{502E}\x{502F}\x{5030}\x{5031}\x{5032}' - . '\x{5033}\x{5035}\x{5036}\x{5037}\x{5039}\x{503A}\x{503B}\x{503C}\x{503E}' - . '\x{503F}\x{5040}\x{5041}\x{5043}\x{5044}\x{5045}\x{5046}\x{5047}\x{5048}' - . '\x{5049}\x{504A}\x{504B}\x{504C}\x{504D}\x{504E}\x{504F}\x{5051}\x{5053}' - . '\x{5054}\x{5055}\x{5056}\x{5057}\x{5059}\x{505A}\x{505B}\x{505C}\x{505D}' - . '\x{505E}\x{505F}\x{5060}\x{5061}\x{5062}\x{5063}\x{5064}\x{5065}\x{5066}' - . '\x{5067}\x{5068}\x{5069}\x{506A}\x{506B}\x{506C}\x{506D}\x{506E}\x{506F}' - . '\x{5070}\x{5071}\x{5072}\x{5073}\x{5074}\x{5075}\x{5076}\x{5077}\x{5078}' - . '\x{5079}\x{507A}\x{507B}\x{507D}\x{507E}\x{507F}\x{5080}\x{5082}\x{5083}' - . '\x{5084}\x{5085}\x{5086}\x{5087}\x{5088}\x{5089}\x{508A}\x{508B}\x{508C}' - . '\x{508D}\x{508E}\x{508F}\x{5090}\x{5091}\x{5092}\x{5094}\x{5095}\x{5096}' - . '\x{5098}\x{5099}\x{509A}\x{509B}\x{509C}\x{509D}\x{509E}\x{50A2}\x{50A3}' - . '\x{50A4}\x{50A5}\x{50A6}\x{50A7}\x{50A8}\x{50A9}\x{50AA}\x{50AB}\x{50AC}' - . '\x{50AD}\x{50AE}\x{50AF}\x{50B0}\x{50B1}\x{50B2}\x{50B3}\x{50B4}\x{50B5}' - . '\x{50B6}\x{50B7}\x{50B8}\x{50BA}\x{50BB}\x{50BC}\x{50BD}\x{50BE}\x{50BF}' - . '\x{50C0}\x{50C1}\x{50C2}\x{50C4}\x{50C5}\x{50C6}\x{50C7}\x{50C8}\x{50C9}' - . '\x{50CA}\x{50CB}\x{50CC}\x{50CD}\x{50CE}\x{50CF}\x{50D0}\x{50D1}\x{50D2}' - . '\x{50D3}\x{50D4}\x{50D5}\x{50D6}\x{50D7}\x{50D9}\x{50DA}\x{50DB}\x{50DC}' - . '\x{50DD}\x{50DE}\x{50E0}\x{50E3}\x{50E4}\x{50E5}\x{50E6}\x{50E7}\x{50E8}' - . '\x{50E9}\x{50EA}\x{50EC}\x{50ED}\x{50EE}\x{50EF}\x{50F0}\x{50F1}\x{50F2}' - . '\x{50F3}\x{50F5}\x{50F6}\x{50F8}\x{50F9}\x{50FA}\x{50FB}\x{50FC}\x{50FD}' - . '\x{50FE}\x{50FF}\x{5100}\x{5101}\x{5102}\x{5103}\x{5104}\x{5105}\x{5106}' - . '\x{5107}\x{5108}\x{5109}\x{510A}\x{510B}\x{510C}\x{510D}\x{510E}\x{510F}' - . '\x{5110}\x{5111}\x{5112}\x{5113}\x{5114}\x{5115}\x{5116}\x{5117}\x{5118}' - . '\x{5119}\x{511A}\x{511C}\x{511D}\x{511E}\x{511F}\x{5120}\x{5121}\x{5122}' - . '\x{5123}\x{5124}\x{5125}\x{5126}\x{5127}\x{5129}\x{512A}\x{512C}\x{512D}' - . '\x{512E}\x{512F}\x{5130}\x{5131}\x{5132}\x{5133}\x{5134}\x{5135}\x{5136}' - . '\x{5137}\x{5138}\x{5139}\x{513A}\x{513B}\x{513C}\x{513D}\x{513E}\x{513F}' - . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' - . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5151}\x{5152}\x{5154}\x{5155}' - . '\x{5156}\x{5157}\x{5159}\x{515A}\x{515B}\x{515C}\x{515D}\x{515E}\x{515F}' - . '\x{5161}\x{5162}\x{5163}\x{5165}\x{5166}\x{5167}\x{5168}\x{5169}\x{516A}' - . '\x{516B}\x{516C}\x{516D}\x{516E}\x{516F}\x{5170}\x{5171}\x{5173}\x{5174}' - . '\x{5175}\x{5176}\x{5177}\x{5178}\x{5179}\x{517A}\x{517B}\x{517C}\x{517D}' - . '\x{517F}\x{5180}\x{5181}\x{5182}\x{5185}\x{5186}\x{5187}\x{5188}\x{5189}' - . '\x{518A}\x{518B}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}\x{5193}' - . '\x{5194}\x{5195}\x{5196}\x{5197}\x{5198}\x{5199}\x{519A}\x{519B}\x{519C}' - . '\x{519D}\x{519E}\x{519F}\x{51A0}\x{51A2}\x{51A4}\x{51A5}\x{51A6}\x{51A7}' - . '\x{51A8}\x{51AA}\x{51AB}\x{51AC}\x{51AE}\x{51AF}\x{51B0}\x{51B1}\x{51B2}' - . '\x{51B3}\x{51B5}\x{51B6}\x{51B7}\x{51B9}\x{51BB}\x{51BC}\x{51BD}\x{51BE}' - . '\x{51BF}\x{51C0}\x{51C1}\x{51C3}\x{51C4}\x{51C5}\x{51C6}\x{51C7}\x{51C8}' - . '\x{51C9}\x{51CA}\x{51CB}\x{51CC}\x{51CD}\x{51CE}\x{51CF}\x{51D0}\x{51D1}' - . '\x{51D4}\x{51D5}\x{51D6}\x{51D7}\x{51D8}\x{51D9}\x{51DA}\x{51DB}\x{51DC}' - . '\x{51DD}\x{51DE}\x{51E0}\x{51E1}\x{51E2}\x{51E3}\x{51E4}\x{51E5}\x{51E7}' - . '\x{51E8}\x{51E9}\x{51EA}\x{51EB}\x{51ED}\x{51EF}\x{51F0}\x{51F1}\x{51F3}' - . '\x{51F4}\x{51F5}\x{51F6}\x{51F7}\x{51F8}\x{51F9}\x{51FA}\x{51FB}\x{51FC}' - . '\x{51FD}\x{51FE}\x{51FF}\x{5200}\x{5201}\x{5202}\x{5203}\x{5204}\x{5205}' - . '\x{5206}\x{5207}\x{5208}\x{5209}\x{520A}\x{520B}\x{520C}\x{520D}\x{520E}' - . '\x{520F}\x{5210}\x{5211}\x{5212}\x{5213}\x{5214}\x{5215}\x{5216}\x{5217}' - . '\x{5218}\x{5219}\x{521A}\x{521B}\x{521C}\x{521D}\x{521E}\x{521F}\x{5220}' - . '\x{5221}\x{5222}\x{5223}\x{5224}\x{5225}\x{5226}\x{5228}\x{5229}\x{522A}' - . '\x{522B}\x{522C}\x{522D}\x{522E}\x{522F}\x{5230}\x{5231}\x{5232}\x{5233}' - . '\x{5234}\x{5235}\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{523C}' - . '\x{523D}\x{523E}\x{523F}\x{5240}\x{5241}\x{5242}\x{5243}\x{5244}\x{5245}' - . '\x{5246}\x{5247}\x{5248}\x{5249}\x{524A}\x{524B}\x{524C}\x{524D}\x{524E}' - . '\x{5250}\x{5251}\x{5252}\x{5254}\x{5255}\x{5256}\x{5257}\x{5258}\x{5259}' - . '\x{525A}\x{525B}\x{525C}\x{525D}\x{525E}\x{525F}\x{5260}\x{5261}\x{5262}' - . '\x{5263}\x{5264}\x{5265}\x{5267}\x{5268}\x{5269}\x{526A}\x{526B}\x{526C}' - . '\x{526D}\x{526E}\x{526F}\x{5270}\x{5272}\x{5273}\x{5274}\x{5275}\x{5276}' - . '\x{5277}\x{5278}\x{527A}\x{527B}\x{527C}\x{527D}\x{527E}\x{527F}\x{5280}' - . '\x{5281}\x{5282}\x{5283}\x{5284}\x{5286}\x{5287}\x{5288}\x{5289}\x{528A}' - . '\x{528B}\x{528C}\x{528D}\x{528F}\x{5290}\x{5291}\x{5292}\x{5293}\x{5294}' - . '\x{5295}\x{5296}\x{5297}\x{5298}\x{5299}\x{529A}\x{529B}\x{529C}\x{529D}' - . '\x{529E}\x{529F}\x{52A0}\x{52A1}\x{52A2}\x{52A3}\x{52A5}\x{52A6}\x{52A7}' - . '\x{52A8}\x{52A9}\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52AE}\x{52AF}\x{52B0}' - . '\x{52B1}\x{52B2}\x{52B3}\x{52B4}\x{52B5}\x{52B6}\x{52B7}\x{52B8}\x{52B9}' - . '\x{52BA}\x{52BB}\x{52BC}\x{52BD}\x{52BE}\x{52BF}\x{52C0}\x{52C1}\x{52C2}' - . '\x{52C3}\x{52C6}\x{52C7}\x{52C9}\x{52CA}\x{52CB}\x{52CD}\x{52CF}\x{52D0}' - . '\x{52D2}\x{52D3}\x{52D5}\x{52D6}\x{52D7}\x{52D8}\x{52D9}\x{52DA}\x{52DB}' - . '\x{52DC}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}\x{52E4}\x{52E6}' - . '\x{52E7}\x{52E8}\x{52E9}\x{52EA}\x{52EB}\x{52EC}\x{52ED}\x{52EF}\x{52F0}' - . '\x{52F1}\x{52F2}\x{52F3}\x{52F4}\x{52F5}\x{52F6}\x{52F7}\x{52F8}\x{52F9}' - . '\x{52FA}\x{52FB}\x{52FC}\x{52FD}\x{52FE}\x{52FF}\x{5300}\x{5301}\x{5302}' - . '\x{5305}\x{5306}\x{5307}\x{5308}\x{5309}\x{530A}\x{530B}\x{530C}\x{530D}' - . '\x{530E}\x{530F}\x{5310}\x{5311}\x{5312}\x{5313}\x{5314}\x{5315}\x{5316}' - . '\x{5317}\x{5319}\x{531A}\x{531C}\x{531D}\x{531F}\x{5320}\x{5321}\x{5322}' - . '\x{5323}\x{5324}\x{5325}\x{5326}\x{5328}\x{532A}\x{532B}\x{532C}\x{532D}' - . '\x{532E}\x{532F}\x{5330}\x{5331}\x{5333}\x{5334}\x{5337}\x{5339}\x{533A}' - . '\x{533B}\x{533C}\x{533D}\x{533E}\x{533F}\x{5340}\x{5341}\x{5343}\x{5344}' - . '\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}\x{534A}\x{534B}\x{534C}\x{534D}' - . '\x{534E}\x{534F}\x{5350}\x{5351}\x{5352}\x{5353}\x{5354}\x{5355}\x{5356}' - . '\x{5357}\x{5358}\x{5359}\x{535A}\x{535C}\x{535E}\x{535F}\x{5360}\x{5361}' - . '\x{5362}\x{5363}\x{5364}\x{5365}\x{5366}\x{5367}\x{5369}\x{536B}\x{536C}' - . '\x{536E}\x{536F}\x{5370}\x{5371}\x{5372}\x{5373}\x{5374}\x{5375}\x{5376}' - . '\x{5377}\x{5378}\x{5379}\x{537A}\x{537B}\x{537C}\x{537D}\x{537E}\x{537F}' - . '\x{5381}\x{5382}\x{5383}\x{5384}\x{5385}\x{5386}\x{5387}\x{5388}\x{5389}' - . '\x{538A}\x{538B}\x{538C}\x{538D}\x{538E}\x{538F}\x{5390}\x{5391}\x{5392}' - . '\x{5393}\x{5394}\x{5395}\x{5396}\x{5397}\x{5398}\x{5399}\x{539A}\x{539B}' - . '\x{539C}\x{539D}\x{539E}\x{539F}\x{53A0}\x{53A2}\x{53A3}\x{53A4}\x{53A5}' - . '\x{53A6}\x{53A7}\x{53A8}\x{53A9}\x{53AC}\x{53AD}\x{53AE}\x{53B0}\x{53B1}' - . '\x{53B2}\x{53B3}\x{53B4}\x{53B5}\x{53B6}\x{53B7}\x{53B8}\x{53B9}\x{53BB}' - . '\x{53BC}\x{53BD}\x{53BE}\x{53BF}\x{53C0}\x{53C1}\x{53C2}\x{53C3}\x{53C4}' - . '\x{53C6}\x{53C7}\x{53C8}\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}' - . '\x{53D0}\x{53D1}\x{53D2}\x{53D3}\x{53D4}\x{53D5}\x{53D6}\x{53D7}\x{53D8}' - . '\x{53D9}\x{53DB}\x{53DC}\x{53DF}\x{53E0}\x{53E1}\x{53E2}\x{53E3}\x{53E4}' - . '\x{53E5}\x{53E6}\x{53E8}\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}' - . '\x{53EF}\x{53F0}\x{53F1}\x{53F2}\x{53F3}\x{53F4}\x{53F5}\x{53F6}\x{53F7}' - . '\x{53F8}\x{53F9}\x{53FA}\x{53FB}\x{53FC}\x{53FD}\x{53FE}\x{5401}\x{5402}' - . '\x{5403}\x{5404}\x{5405}\x{5406}\x{5407}\x{5408}\x{5409}\x{540A}\x{540B}' - . '\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}\x{5411}\x{5412}\x{5413}\x{5414}' - . '\x{5415}\x{5416}\x{5417}\x{5418}\x{5419}\x{541B}\x{541C}\x{541D}\x{541E}' - . '\x{541F}\x{5420}\x{5421}\x{5423}\x{5424}\x{5425}\x{5426}\x{5427}\x{5428}' - . '\x{5429}\x{542A}\x{542B}\x{542C}\x{542D}\x{542E}\x{542F}\x{5430}\x{5431}' - . '\x{5432}\x{5433}\x{5434}\x{5435}\x{5436}\x{5437}\x{5438}\x{5439}\x{543A}' - . '\x{543B}\x{543C}\x{543D}\x{543E}\x{543F}\x{5440}\x{5441}\x{5442}\x{5443}' - . '\x{5444}\x{5445}\x{5446}\x{5447}\x{5448}\x{5449}\x{544A}\x{544B}\x{544D}' - . '\x{544E}\x{544F}\x{5450}\x{5451}\x{5452}\x{5453}\x{5454}\x{5455}\x{5456}' - . '\x{5457}\x{5458}\x{5459}\x{545A}\x{545B}\x{545C}\x{545E}\x{545F}\x{5460}' - . '\x{5461}\x{5462}\x{5463}\x{5464}\x{5465}\x{5466}\x{5467}\x{5468}\x{546A}' - . '\x{546B}\x{546C}\x{546D}\x{546E}\x{546F}\x{5470}\x{5471}\x{5472}\x{5473}' - . '\x{5474}\x{5475}\x{5476}\x{5477}\x{5478}\x{5479}\x{547A}\x{547B}\x{547C}' - . '\x{547D}\x{547E}\x{547F}\x{5480}\x{5481}\x{5482}\x{5483}\x{5484}\x{5485}' - . '\x{5486}\x{5487}\x{5488}\x{5489}\x{548B}\x{548C}\x{548D}\x{548E}\x{548F}' - . '\x{5490}\x{5491}\x{5492}\x{5493}\x{5494}\x{5495}\x{5496}\x{5497}\x{5498}' - . '\x{5499}\x{549A}\x{549B}\x{549C}\x{549D}\x{549E}\x{549F}\x{54A0}\x{54A1}' - . '\x{54A2}\x{54A3}\x{54A4}\x{54A5}\x{54A6}\x{54A7}\x{54A8}\x{54A9}\x{54AA}' - . '\x{54AB}\x{54AC}\x{54AD}\x{54AE}\x{54AF}\x{54B0}\x{54B1}\x{54B2}\x{54B3}' - . '\x{54B4}\x{54B6}\x{54B7}\x{54B8}\x{54B9}\x{54BA}\x{54BB}\x{54BC}\x{54BD}' - . '\x{54BE}\x{54BF}\x{54C0}\x{54C1}\x{54C2}\x{54C3}\x{54C4}\x{54C5}\x{54C6}' - . '\x{54C7}\x{54C8}\x{54C9}\x{54CA}\x{54CB}\x{54CC}\x{54CD}\x{54CE}\x{54CF}' - . '\x{54D0}\x{54D1}\x{54D2}\x{54D3}\x{54D4}\x{54D5}\x{54D6}\x{54D7}\x{54D8}' - . '\x{54D9}\x{54DA}\x{54DB}\x{54DC}\x{54DD}\x{54DE}\x{54DF}\x{54E0}\x{54E1}' - . '\x{54E2}\x{54E3}\x{54E4}\x{54E5}\x{54E6}\x{54E7}\x{54E8}\x{54E9}\x{54EA}' - . '\x{54EB}\x{54EC}\x{54ED}\x{54EE}\x{54EF}\x{54F0}\x{54F1}\x{54F2}\x{54F3}' - . '\x{54F4}\x{54F5}\x{54F7}\x{54F8}\x{54F9}\x{54FA}\x{54FB}\x{54FC}\x{54FD}' - . '\x{54FE}\x{54FF}\x{5500}\x{5501}\x{5502}\x{5503}\x{5504}\x{5505}\x{5506}' - . '\x{5507}\x{5508}\x{5509}\x{550A}\x{550B}\x{550C}\x{550D}\x{550E}\x{550F}' - . '\x{5510}\x{5511}\x{5512}\x{5513}\x{5514}\x{5516}\x{5517}\x{551A}\x{551B}' - . '\x{551C}\x{551D}\x{551E}\x{551F}\x{5520}\x{5521}\x{5522}\x{5523}\x{5524}' - . '\x{5525}\x{5526}\x{5527}\x{5528}\x{5529}\x{552A}\x{552B}\x{552C}\x{552D}' - . '\x{552E}\x{552F}\x{5530}\x{5531}\x{5532}\x{5533}\x{5534}\x{5535}\x{5536}' - . '\x{5537}\x{5538}\x{5539}\x{553A}\x{553B}\x{553C}\x{553D}\x{553E}\x{553F}' - . '\x{5540}\x{5541}\x{5542}\x{5543}\x{5544}\x{5545}\x{5546}\x{5548}\x{5549}' - . '\x{554A}\x{554B}\x{554C}\x{554D}\x{554E}\x{554F}\x{5550}\x{5551}\x{5552}' - . '\x{5553}\x{5554}\x{5555}\x{5556}\x{5557}\x{5558}\x{5559}\x{555A}\x{555B}' - . '\x{555C}\x{555D}\x{555E}\x{555F}\x{5561}\x{5562}\x{5563}\x{5564}\x{5565}' - . '\x{5566}\x{5567}\x{5568}\x{5569}\x{556A}\x{556B}\x{556C}\x{556D}\x{556E}' - . '\x{556F}\x{5570}\x{5571}\x{5572}\x{5573}\x{5574}\x{5575}\x{5576}\x{5577}' - . '\x{5578}\x{5579}\x{557B}\x{557C}\x{557D}\x{557E}\x{557F}\x{5580}\x{5581}' - . '\x{5582}\x{5583}\x{5584}\x{5585}\x{5586}\x{5587}\x{5588}\x{5589}\x{558A}' - . '\x{558B}\x{558C}\x{558D}\x{558E}\x{558F}\x{5590}\x{5591}\x{5592}\x{5593}' - . '\x{5594}\x{5595}\x{5596}\x{5597}\x{5598}\x{5599}\x{559A}\x{559B}\x{559C}' - . '\x{559D}\x{559E}\x{559F}\x{55A0}\x{55A1}\x{55A2}\x{55A3}\x{55A4}\x{55A5}' - . '\x{55A6}\x{55A7}\x{55A8}\x{55A9}\x{55AA}\x{55AB}\x{55AC}\x{55AD}\x{55AE}' - . '\x{55AF}\x{55B0}\x{55B1}\x{55B2}\x{55B3}\x{55B4}\x{55B5}\x{55B6}\x{55B7}' - . '\x{55B8}\x{55B9}\x{55BA}\x{55BB}\x{55BC}\x{55BD}\x{55BE}\x{55BF}\x{55C0}' - . '\x{55C1}\x{55C2}\x{55C3}\x{55C4}\x{55C5}\x{55C6}\x{55C7}\x{55C8}\x{55C9}' - . '\x{55CA}\x{55CB}\x{55CC}\x{55CD}\x{55CE}\x{55CF}\x{55D0}\x{55D1}\x{55D2}' - . '\x{55D3}\x{55D4}\x{55D5}\x{55D6}\x{55D7}\x{55D8}\x{55D9}\x{55DA}\x{55DB}' - . '\x{55DC}\x{55DD}\x{55DE}\x{55DF}\x{55E1}\x{55E2}\x{55E3}\x{55E4}\x{55E5}' - . '\x{55E6}\x{55E7}\x{55E8}\x{55E9}\x{55EA}\x{55EB}\x{55EC}\x{55ED}\x{55EE}' - . '\x{55EF}\x{55F0}\x{55F1}\x{55F2}\x{55F3}\x{55F4}\x{55F5}\x{55F6}\x{55F7}' - . '\x{55F9}\x{55FA}\x{55FB}\x{55FC}\x{55FD}\x{55FE}\x{55FF}\x{5600}\x{5601}' - . '\x{5602}\x{5603}\x{5604}\x{5606}\x{5607}\x{5608}\x{5609}\x{560C}\x{560D}' - . '\x{560E}\x{560F}\x{5610}\x{5611}\x{5612}\x{5613}\x{5614}\x{5615}\x{5616}' - . '\x{5617}\x{5618}\x{5619}\x{561A}\x{561B}\x{561C}\x{561D}\x{561E}\x{561F}' - . '\x{5621}\x{5622}\x{5623}\x{5624}\x{5625}\x{5626}\x{5627}\x{5628}\x{5629}' - . '\x{562A}\x{562C}\x{562D}\x{562E}\x{562F}\x{5630}\x{5631}\x{5632}\x{5633}' - . '\x{5634}\x{5635}\x{5636}\x{5638}\x{5639}\x{563A}\x{563B}\x{563D}\x{563E}' - . '\x{563F}\x{5640}\x{5641}\x{5642}\x{5643}\x{5645}\x{5646}\x{5647}\x{5648}' - . '\x{5649}\x{564A}\x{564C}\x{564D}\x{564E}\x{564F}\x{5650}\x{5652}\x{5653}' - . '\x{5654}\x{5655}\x{5657}\x{5658}\x{5659}\x{565A}\x{565B}\x{565C}\x{565D}' - . '\x{565E}\x{5660}\x{5662}\x{5663}\x{5664}\x{5665}\x{5666}\x{5667}\x{5668}' - . '\x{5669}\x{566A}\x{566B}\x{566C}\x{566D}\x{566E}\x{566F}\x{5670}\x{5671}' - . '\x{5672}\x{5673}\x{5674}\x{5676}\x{5677}\x{5678}\x{5679}\x{567A}\x{567B}' - . '\x{567C}\x{567E}\x{567F}\x{5680}\x{5681}\x{5682}\x{5683}\x{5684}\x{5685}' - . '\x{5686}\x{5687}\x{568A}\x{568C}\x{568D}\x{568E}\x{568F}\x{5690}\x{5691}' - . '\x{5692}\x{5693}\x{5694}\x{5695}\x{5697}\x{5698}\x{5699}\x{569A}\x{569B}' - . '\x{569C}\x{569D}\x{569F}\x{56A0}\x{56A1}\x{56A3}\x{56A4}\x{56A5}\x{56A6}' - . '\x{56A7}\x{56A8}\x{56A9}\x{56AA}\x{56AB}\x{56AC}\x{56AD}\x{56AE}\x{56AF}' - . '\x{56B0}\x{56B1}\x{56B2}\x{56B3}\x{56B4}\x{56B5}\x{56B6}\x{56B7}\x{56B8}' - . '\x{56B9}\x{56BB}\x{56BC}\x{56BD}\x{56BE}\x{56BF}\x{56C0}\x{56C1}\x{56C2}' - . '\x{56C3}\x{56C4}\x{56C5}\x{56C6}\x{56C7}\x{56C8}\x{56C9}\x{56CA}\x{56CB}' - . '\x{56CC}\x{56CD}\x{56CE}\x{56D0}\x{56D1}\x{56D2}\x{56D3}\x{56D4}\x{56D5}' - . '\x{56D6}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DC}\x{56DD}\x{56DE}\x{56DF}' - . '\x{56E0}\x{56E1}\x{56E2}\x{56E3}\x{56E4}\x{56E5}\x{56E7}\x{56E8}\x{56E9}' - . '\x{56EA}\x{56EB}\x{56EC}\x{56ED}\x{56EE}\x{56EF}\x{56F0}\x{56F1}\x{56F2}' - . '\x{56F3}\x{56F4}\x{56F5}\x{56F7}\x{56F9}\x{56FA}\x{56FD}\x{56FE}\x{56FF}' - . '\x{5700}\x{5701}\x{5702}\x{5703}\x{5704}\x{5706}\x{5707}\x{5708}\x{5709}' - . '\x{570A}\x{570B}\x{570C}\x{570D}\x{570E}\x{570F}\x{5710}\x{5712}\x{5713}' - . '\x{5714}\x{5715}\x{5716}\x{5718}\x{5719}\x{571A}\x{571B}\x{571C}\x{571D}' - . '\x{571E}\x{571F}\x{5720}\x{5722}\x{5723}\x{5725}\x{5726}\x{5727}\x{5728}' - . '\x{5729}\x{572A}\x{572B}\x{572C}\x{572D}\x{572E}\x{572F}\x{5730}\x{5731}' - . '\x{5732}\x{5733}\x{5734}\x{5735}\x{5736}\x{5737}\x{5738}\x{5739}\x{573A}' - . '\x{573B}\x{573C}\x{573E}\x{573F}\x{5740}\x{5741}\x{5742}\x{5744}\x{5745}' - . '\x{5746}\x{5747}\x{5749}\x{574A}\x{574B}\x{574C}\x{574D}\x{574E}\x{574F}' - . '\x{5750}\x{5751}\x{5752}\x{5753}\x{5754}\x{5757}\x{5759}\x{575A}\x{575B}' - . '\x{575C}\x{575D}\x{575E}\x{575F}\x{5760}\x{5761}\x{5762}\x{5764}\x{5765}' - . '\x{5766}\x{5767}\x{5768}\x{5769}\x{576A}\x{576B}\x{576C}\x{576D}\x{576F}' - . '\x{5770}\x{5771}\x{5772}\x{5773}\x{5774}\x{5775}\x{5776}\x{5777}\x{5779}' - . '\x{577A}\x{577B}\x{577C}\x{577D}\x{577E}\x{577F}\x{5780}\x{5782}\x{5783}' - . '\x{5784}\x{5785}\x{5786}\x{5788}\x{5789}\x{578A}\x{578B}\x{578C}\x{578D}' - . '\x{578E}\x{578F}\x{5790}\x{5791}\x{5792}\x{5793}\x{5794}\x{5795}\x{5797}' - . '\x{5798}\x{5799}\x{579A}\x{579B}\x{579C}\x{579D}\x{579E}\x{579F}\x{57A0}' - . '\x{57A1}\x{57A2}\x{57A3}\x{57A4}\x{57A5}\x{57A6}\x{57A7}\x{57A9}\x{57AA}' - . '\x{57AB}\x{57AC}\x{57AD}\x{57AE}\x{57AF}\x{57B0}\x{57B1}\x{57B2}\x{57B3}' - . '\x{57B4}\x{57B5}\x{57B6}\x{57B7}\x{57B8}\x{57B9}\x{57BA}\x{57BB}\x{57BC}' - . '\x{57BD}\x{57BE}\x{57BF}\x{57C0}\x{57C1}\x{57C2}\x{57C3}\x{57C4}\x{57C5}' - . '\x{57C6}\x{57C7}\x{57C8}\x{57C9}\x{57CB}\x{57CC}\x{57CD}\x{57CE}\x{57CF}' - . '\x{57D0}\x{57D2}\x{57D3}\x{57D4}\x{57D5}\x{57D6}\x{57D8}\x{57D9}\x{57DA}' - . '\x{57DC}\x{57DD}\x{57DF}\x{57E0}\x{57E1}\x{57E2}\x{57E3}\x{57E4}\x{57E5}' - . '\x{57E6}\x{57E7}\x{57E8}\x{57E9}\x{57EA}\x{57EB}\x{57EC}\x{57ED}\x{57EE}' - . '\x{57EF}\x{57F0}\x{57F1}\x{57F2}\x{57F3}\x{57F4}\x{57F5}\x{57F6}\x{57F7}' - . '\x{57F8}\x{57F9}\x{57FA}\x{57FB}\x{57FC}\x{57FD}\x{57FE}\x{57FF}\x{5800}' - . '\x{5801}\x{5802}\x{5803}\x{5804}\x{5805}\x{5806}\x{5807}\x{5808}\x{5809}' - . '\x{580A}\x{580B}\x{580C}\x{580D}\x{580E}\x{580F}\x{5810}\x{5811}\x{5812}' - . '\x{5813}\x{5814}\x{5815}\x{5816}\x{5819}\x{581A}\x{581B}\x{581C}\x{581D}' - . '\x{581E}\x{581F}\x{5820}\x{5821}\x{5822}\x{5823}\x{5824}\x{5825}\x{5826}' - . '\x{5827}\x{5828}\x{5829}\x{582A}\x{582B}\x{582C}\x{582D}\x{582E}\x{582F}' - . '\x{5830}\x{5831}\x{5832}\x{5833}\x{5834}\x{5835}\x{5836}\x{5837}\x{5838}' - . '\x{5839}\x{583A}\x{583B}\x{583C}\x{583D}\x{583E}\x{583F}\x{5840}\x{5842}' - . '\x{5843}\x{5844}\x{5845}\x{5846}\x{5847}\x{5848}\x{5849}\x{584A}\x{584B}' - . '\x{584C}\x{584D}\x{584E}\x{584F}\x{5851}\x{5852}\x{5853}\x{5854}\x{5855}' - . '\x{5857}\x{5858}\x{5859}\x{585A}\x{585B}\x{585C}\x{585D}\x{585E}\x{585F}' - . '\x{5861}\x{5862}\x{5863}\x{5864}\x{5865}\x{5868}\x{5869}\x{586A}\x{586B}' - . '\x{586C}\x{586D}\x{586E}\x{586F}\x{5870}\x{5871}\x{5872}\x{5873}\x{5874}' - . '\x{5875}\x{5876}\x{5878}\x{5879}\x{587A}\x{587B}\x{587C}\x{587D}\x{587E}' - . '\x{587F}\x{5880}\x{5881}\x{5882}\x{5883}\x{5884}\x{5885}\x{5886}\x{5887}' - . '\x{5888}\x{5889}\x{588A}\x{588B}\x{588C}\x{588D}\x{588E}\x{588F}\x{5890}' - . '\x{5891}\x{5892}\x{5893}\x{5894}\x{5896}\x{5897}\x{5898}\x{5899}\x{589A}' - . '\x{589B}\x{589C}\x{589D}\x{589E}\x{589F}\x{58A0}\x{58A1}\x{58A2}\x{58A3}' - . '\x{58A4}\x{58A5}\x{58A6}\x{58A7}\x{58A8}\x{58A9}\x{58AB}\x{58AC}\x{58AD}' - . '\x{58AE}\x{58AF}\x{58B0}\x{58B1}\x{58B2}\x{58B3}\x{58B4}\x{58B7}\x{58B8}' - . '\x{58B9}\x{58BA}\x{58BB}\x{58BC}\x{58BD}\x{58BE}\x{58BF}\x{58C1}\x{58C2}' - . '\x{58C5}\x{58C6}\x{58C7}\x{58C8}\x{58C9}\x{58CA}\x{58CB}\x{58CE}\x{58CF}' - . '\x{58D1}\x{58D2}\x{58D3}\x{58D4}\x{58D5}\x{58D6}\x{58D7}\x{58D8}\x{58D9}' - . '\x{58DA}\x{58DB}\x{58DD}\x{58DE}\x{58DF}\x{58E0}\x{58E2}\x{58E3}\x{58E4}' - . '\x{58E5}\x{58E7}\x{58E8}\x{58E9}\x{58EA}\x{58EB}\x{58EC}\x{58ED}\x{58EE}' - . '\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F3}\x{58F4}\x{58F6}\x{58F7}\x{58F8}' - . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{58FE}\x{58FF}\x{5900}\x{5902}' - . '\x{5903}\x{5904}\x{5906}\x{5907}\x{5909}\x{590A}\x{590B}\x{590C}\x{590D}' - . '\x{590E}\x{590F}\x{5910}\x{5912}\x{5914}\x{5915}\x{5916}\x{5917}\x{5918}' - . '\x{5919}\x{591A}\x{591B}\x{591C}\x{591D}\x{591E}\x{591F}\x{5920}\x{5921}' - . '\x{5922}\x{5924}\x{5925}\x{5926}\x{5927}\x{5928}\x{5929}\x{592A}\x{592B}' - . '\x{592C}\x{592D}\x{592E}\x{592F}\x{5930}\x{5931}\x{5932}\x{5934}\x{5935}' - . '\x{5937}\x{5938}\x{5939}\x{593A}\x{593B}\x{593C}\x{593D}\x{593E}\x{593F}' - . '\x{5940}\x{5941}\x{5942}\x{5943}\x{5944}\x{5945}\x{5946}\x{5947}\x{5948}' - . '\x{5949}\x{594A}\x{594B}\x{594C}\x{594D}\x{594E}\x{594F}\x{5950}\x{5951}' - . '\x{5952}\x{5953}\x{5954}\x{5955}\x{5956}\x{5957}\x{5958}\x{595A}\x{595C}' - . '\x{595D}\x{595E}\x{595F}\x{5960}\x{5961}\x{5962}\x{5963}\x{5964}\x{5965}' - . '\x{5966}\x{5967}\x{5968}\x{5969}\x{596A}\x{596B}\x{596C}\x{596D}\x{596E}' - . '\x{596F}\x{5970}\x{5971}\x{5972}\x{5973}\x{5974}\x{5975}\x{5976}\x{5977}' - . '\x{5978}\x{5979}\x{597A}\x{597B}\x{597C}\x{597D}\x{597E}\x{597F}\x{5980}' - . '\x{5981}\x{5982}\x{5983}\x{5984}\x{5985}\x{5986}\x{5987}\x{5988}\x{5989}' - . '\x{598A}\x{598B}\x{598C}\x{598D}\x{598E}\x{598F}\x{5990}\x{5991}\x{5992}' - . '\x{5993}\x{5994}\x{5995}\x{5996}\x{5997}\x{5998}\x{5999}\x{599A}\x{599C}' - . '\x{599D}\x{599E}\x{599F}\x{59A0}\x{59A1}\x{59A2}\x{59A3}\x{59A4}\x{59A5}' - . '\x{59A6}\x{59A7}\x{59A8}\x{59A9}\x{59AA}\x{59AB}\x{59AC}\x{59AD}\x{59AE}' - . '\x{59AF}\x{59B0}\x{59B1}\x{59B2}\x{59B3}\x{59B4}\x{59B5}\x{59B6}\x{59B8}' - . '\x{59B9}\x{59BA}\x{59BB}\x{59BC}\x{59BD}\x{59BE}\x{59BF}\x{59C0}\x{59C1}' - . '\x{59C2}\x{59C3}\x{59C4}\x{59C5}\x{59C6}\x{59C7}\x{59C8}\x{59C9}\x{59CA}' - . '\x{59CB}\x{59CC}\x{59CD}\x{59CE}\x{59CF}\x{59D0}\x{59D1}\x{59D2}\x{59D3}' - . '\x{59D4}\x{59D5}\x{59D6}\x{59D7}\x{59D8}\x{59D9}\x{59DA}\x{59DB}\x{59DC}' - . '\x{59DD}\x{59DE}\x{59DF}\x{59E0}\x{59E1}\x{59E2}\x{59E3}\x{59E4}\x{59E5}' - . '\x{59E6}\x{59E8}\x{59E9}\x{59EA}\x{59EB}\x{59EC}\x{59ED}\x{59EE}\x{59EF}' - . '\x{59F0}\x{59F1}\x{59F2}\x{59F3}\x{59F4}\x{59F5}\x{59F6}\x{59F7}\x{59F8}' - . '\x{59F9}\x{59FA}\x{59FB}\x{59FC}\x{59FD}\x{59FE}\x{59FF}\x{5A00}\x{5A01}' - . '\x{5A02}\x{5A03}\x{5A04}\x{5A05}\x{5A06}\x{5A07}\x{5A08}\x{5A09}\x{5A0A}' - . '\x{5A0B}\x{5A0C}\x{5A0D}\x{5A0E}\x{5A0F}\x{5A10}\x{5A11}\x{5A12}\x{5A13}' - . '\x{5A14}\x{5A15}\x{5A16}\x{5A17}\x{5A18}\x{5A19}\x{5A1A}\x{5A1B}\x{5A1C}' - . '\x{5A1D}\x{5A1E}\x{5A1F}\x{5A20}\x{5A21}\x{5A22}\x{5A23}\x{5A25}\x{5A27}' - . '\x{5A28}\x{5A29}\x{5A2A}\x{5A2B}\x{5A2D}\x{5A2E}\x{5A2F}\x{5A31}\x{5A32}' - . '\x{5A33}\x{5A34}\x{5A35}\x{5A36}\x{5A37}\x{5A38}\x{5A39}\x{5A3A}\x{5A3B}' - . '\x{5A3C}\x{5A3D}\x{5A3E}\x{5A3F}\x{5A40}\x{5A41}\x{5A42}\x{5A43}\x{5A44}' - . '\x{5A45}\x{5A46}\x{5A47}\x{5A48}\x{5A49}\x{5A4A}\x{5A4B}\x{5A4C}\x{5A4D}' - . '\x{5A4E}\x{5A4F}\x{5A50}\x{5A51}\x{5A52}\x{5A53}\x{5A55}\x{5A56}\x{5A57}' - . '\x{5A58}\x{5A5A}\x{5A5B}\x{5A5C}\x{5A5D}\x{5A5E}\x{5A5F}\x{5A60}\x{5A61}' - . '\x{5A62}\x{5A63}\x{5A64}\x{5A65}\x{5A66}\x{5A67}\x{5A68}\x{5A69}\x{5A6A}' - . '\x{5A6B}\x{5A6C}\x{5A6D}\x{5A6E}\x{5A70}\x{5A72}\x{5A73}\x{5A74}\x{5A75}' - . '\x{5A76}\x{5A77}\x{5A78}\x{5A79}\x{5A7A}\x{5A7B}\x{5A7C}\x{5A7D}\x{5A7E}' - . '\x{5A7F}\x{5A80}\x{5A81}\x{5A82}\x{5A83}\x{5A84}\x{5A85}\x{5A86}\x{5A88}' - . '\x{5A89}\x{5A8A}\x{5A8B}\x{5A8C}\x{5A8E}\x{5A8F}\x{5A90}\x{5A91}\x{5A92}' - . '\x{5A93}\x{5A94}\x{5A95}\x{5A96}\x{5A97}\x{5A98}\x{5A99}\x{5A9A}\x{5A9B}' - . '\x{5A9C}\x{5A9D}\x{5A9E}\x{5A9F}\x{5AA0}\x{5AA1}\x{5AA2}\x{5AA3}\x{5AA4}' - . '\x{5AA5}\x{5AA6}\x{5AA7}\x{5AA8}\x{5AA9}\x{5AAA}\x{5AAC}\x{5AAD}\x{5AAE}' - . '\x{5AAF}\x{5AB0}\x{5AB1}\x{5AB2}\x{5AB3}\x{5AB4}\x{5AB5}\x{5AB6}\x{5AB7}' - . '\x{5AB8}\x{5AB9}\x{5ABA}\x{5ABB}\x{5ABC}\x{5ABD}\x{5ABE}\x{5ABF}\x{5AC0}' - . '\x{5AC1}\x{5AC2}\x{5AC3}\x{5AC4}\x{5AC5}\x{5AC6}\x{5AC7}\x{5AC8}\x{5AC9}' - . '\x{5ACA}\x{5ACB}\x{5ACC}\x{5ACD}\x{5ACE}\x{5ACF}\x{5AD1}\x{5AD2}\x{5AD4}' - . '\x{5AD5}\x{5AD6}\x{5AD7}\x{5AD8}\x{5AD9}\x{5ADA}\x{5ADB}\x{5ADC}\x{5ADD}' - . '\x{5ADE}\x{5ADF}\x{5AE0}\x{5AE1}\x{5AE2}\x{5AE3}\x{5AE4}\x{5AE5}\x{5AE6}' - . '\x{5AE7}\x{5AE8}\x{5AE9}\x{5AEA}\x{5AEB}\x{5AEC}\x{5AED}\x{5AEE}\x{5AF1}' - . '\x{5AF2}\x{5AF3}\x{5AF4}\x{5AF5}\x{5AF6}\x{5AF7}\x{5AF8}\x{5AF9}\x{5AFA}' - . '\x{5AFB}\x{5AFC}\x{5AFD}\x{5AFE}\x{5AFF}\x{5B00}\x{5B01}\x{5B02}\x{5B03}' - . '\x{5B04}\x{5B05}\x{5B06}\x{5B07}\x{5B08}\x{5B09}\x{5B0B}\x{5B0C}\x{5B0E}' - . '\x{5B0F}\x{5B10}\x{5B11}\x{5B12}\x{5B13}\x{5B14}\x{5B15}\x{5B16}\x{5B17}' - . '\x{5B18}\x{5B19}\x{5B1A}\x{5B1B}\x{5B1C}\x{5B1D}\x{5B1E}\x{5B1F}\x{5B20}' - . '\x{5B21}\x{5B22}\x{5B23}\x{5B24}\x{5B25}\x{5B26}\x{5B27}\x{5B28}\x{5B29}' - . '\x{5B2A}\x{5B2B}\x{5B2C}\x{5B2D}\x{5B2E}\x{5B2F}\x{5B30}\x{5B31}\x{5B32}' - . '\x{5B33}\x{5B34}\x{5B35}\x{5B36}\x{5B37}\x{5B38}\x{5B3A}\x{5B3B}\x{5B3C}' - . '\x{5B3D}\x{5B3E}\x{5B3F}\x{5B40}\x{5B41}\x{5B42}\x{5B43}\x{5B44}\x{5B45}' - . '\x{5B47}\x{5B48}\x{5B49}\x{5B4A}\x{5B4B}\x{5B4C}\x{5B4D}\x{5B4E}\x{5B50}' - . '\x{5B51}\x{5B53}\x{5B54}\x{5B55}\x{5B56}\x{5B57}\x{5B58}\x{5B59}\x{5B5A}' - . '\x{5B5B}\x{5B5C}\x{5B5D}\x{5B5E}\x{5B5F}\x{5B62}\x{5B63}\x{5B64}\x{5B65}' - . '\x{5B66}\x{5B67}\x{5B68}\x{5B69}\x{5B6A}\x{5B6B}\x{5B6C}\x{5B6D}\x{5B6E}' - . '\x{5B70}\x{5B71}\x{5B72}\x{5B73}\x{5B74}\x{5B75}\x{5B76}\x{5B77}\x{5B78}' - . '\x{5B7A}\x{5B7B}\x{5B7C}\x{5B7D}\x{5B7F}\x{5B80}\x{5B81}\x{5B82}\x{5B83}' - . '\x{5B84}\x{5B85}\x{5B87}\x{5B88}\x{5B89}\x{5B8A}\x{5B8B}\x{5B8C}\x{5B8D}' - . '\x{5B8E}\x{5B8F}\x{5B91}\x{5B92}\x{5B93}\x{5B94}\x{5B95}\x{5B96}\x{5B97}' - . '\x{5B98}\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9E}\x{5B9F}\x{5BA0}' - . '\x{5BA1}\x{5BA2}\x{5BA3}\x{5BA4}\x{5BA5}\x{5BA6}\x{5BA7}\x{5BA8}\x{5BAA}' - . '\x{5BAB}\x{5BAC}\x{5BAD}\x{5BAE}\x{5BAF}\x{5BB0}\x{5BB1}\x{5BB3}\x{5BB4}' - . '\x{5BB5}\x{5BB6}\x{5BB8}\x{5BB9}\x{5BBA}\x{5BBB}\x{5BBD}\x{5BBE}\x{5BBF}' - . '\x{5BC0}\x{5BC1}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BCA}' - . '\x{5BCB}\x{5BCC}\x{5BCD}\x{5BCE}\x{5BCF}\x{5BD0}\x{5BD1}\x{5BD2}\x{5BD3}' - . '\x{5BD4}\x{5BD5}\x{5BD6}\x{5BD8}\x{5BD9}\x{5BDB}\x{5BDC}\x{5BDD}\x{5BDE}' - . '\x{5BDF}\x{5BE0}\x{5BE1}\x{5BE2}\x{5BE3}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}' - . '\x{5BE8}\x{5BE9}\x{5BEA}\x{5BEB}\x{5BEC}\x{5BED}\x{5BEE}\x{5BEF}\x{5BF0}' - . '\x{5BF1}\x{5BF2}\x{5BF3}\x{5BF4}\x{5BF5}\x{5BF6}\x{5BF7}\x{5BF8}\x{5BF9}' - . '\x{5BFA}\x{5BFB}\x{5BFC}\x{5BFD}\x{5BFF}\x{5C01}\x{5C03}\x{5C04}\x{5C05}' - . '\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}\x{5C0B}\x{5C0C}\x{5C0D}\x{5C0E}' - . '\x{5C0F}\x{5C10}\x{5C11}\x{5C12}\x{5C13}\x{5C14}\x{5C15}\x{5C16}\x{5C17}' - . '\x{5C18}\x{5C19}\x{5C1A}\x{5C1C}\x{5C1D}\x{5C1E}\x{5C1F}\x{5C20}\x{5C21}' - . '\x{5C22}\x{5C24}\x{5C25}\x{5C27}\x{5C28}\x{5C2A}\x{5C2B}\x{5C2C}\x{5C2D}' - . '\x{5C2E}\x{5C2F}\x{5C30}\x{5C31}\x{5C32}\x{5C33}\x{5C34}\x{5C35}\x{5C37}' - . '\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}' - . '\x{5C41}\x{5C42}\x{5C43}\x{5C44}\x{5C45}\x{5C46}\x{5C47}\x{5C48}\x{5C49}' - . '\x{5C4A}\x{5C4B}\x{5C4C}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C52}' - . '\x{5C53}\x{5C54}\x{5C55}\x{5C56}\x{5C57}\x{5C58}\x{5C59}\x{5C5B}\x{5C5C}' - . '\x{5C5D}\x{5C5E}\x{5C5F}\x{5C60}\x{5C61}\x{5C62}\x{5C63}\x{5C64}\x{5C65}' - . '\x{5C66}\x{5C67}\x{5C68}\x{5C69}\x{5C6A}\x{5C6B}\x{5C6C}\x{5C6D}\x{5C6E}' - . '\x{5C6F}\x{5C70}\x{5C71}\x{5C72}\x{5C73}\x{5C74}\x{5C75}\x{5C76}\x{5C77}' - . '\x{5C78}\x{5C79}\x{5C7A}\x{5C7B}\x{5C7C}\x{5C7D}\x{5C7E}\x{5C7F}\x{5C80}' - . '\x{5C81}\x{5C82}\x{5C83}\x{5C84}\x{5C86}\x{5C87}\x{5C88}\x{5C89}\x{5C8A}' - . '\x{5C8B}\x{5C8C}\x{5C8D}\x{5C8E}\x{5C8F}\x{5C90}\x{5C91}\x{5C92}\x{5C93}' - . '\x{5C94}\x{5C95}\x{5C96}\x{5C97}\x{5C98}\x{5C99}\x{5C9A}\x{5C9B}\x{5C9C}' - . '\x{5C9D}\x{5C9E}\x{5C9F}\x{5CA0}\x{5CA1}\x{5CA2}\x{5CA3}\x{5CA4}\x{5CA5}' - . '\x{5CA6}\x{5CA7}\x{5CA8}\x{5CA9}\x{5CAA}\x{5CAB}\x{5CAC}\x{5CAD}\x{5CAE}' - . '\x{5CAF}\x{5CB0}\x{5CB1}\x{5CB2}\x{5CB3}\x{5CB5}\x{5CB6}\x{5CB7}\x{5CB8}' - . '\x{5CBA}\x{5CBB}\x{5CBC}\x{5CBD}\x{5CBE}\x{5CBF}\x{5CC1}\x{5CC2}\x{5CC3}' - . '\x{5CC4}\x{5CC5}\x{5CC6}\x{5CC7}\x{5CC8}\x{5CC9}\x{5CCA}\x{5CCB}\x{5CCC}' - . '\x{5CCD}\x{5CCE}\x{5CCF}\x{5CD0}\x{5CD1}\x{5CD2}\x{5CD3}\x{5CD4}\x{5CD6}' - . '\x{5CD7}\x{5CD8}\x{5CD9}\x{5CDA}\x{5CDB}\x{5CDC}\x{5CDE}\x{5CDF}\x{5CE0}' - . '\x{5CE1}\x{5CE2}\x{5CE3}\x{5CE4}\x{5CE5}\x{5CE6}\x{5CE7}\x{5CE8}\x{5CE9}' - . '\x{5CEA}\x{5CEB}\x{5CEC}\x{5CED}\x{5CEE}\x{5CEF}\x{5CF0}\x{5CF1}\x{5CF2}' - . '\x{5CF3}\x{5CF4}\x{5CF6}\x{5CF7}\x{5CF8}\x{5CF9}\x{5CFA}\x{5CFB}\x{5CFC}' - . '\x{5CFD}\x{5CFE}\x{5CFF}\x{5D00}\x{5D01}\x{5D02}\x{5D03}\x{5D04}\x{5D05}' - . '\x{5D06}\x{5D07}\x{5D08}\x{5D09}\x{5D0A}\x{5D0B}\x{5D0C}\x{5D0D}\x{5D0E}' - . '\x{5D0F}\x{5D10}\x{5D11}\x{5D12}\x{5D13}\x{5D14}\x{5D15}\x{5D16}\x{5D17}' - . '\x{5D18}\x{5D19}\x{5D1A}\x{5D1B}\x{5D1C}\x{5D1D}\x{5D1E}\x{5D1F}\x{5D20}' - . '\x{5D21}\x{5D22}\x{5D23}\x{5D24}\x{5D25}\x{5D26}\x{5D27}\x{5D28}\x{5D29}' - . '\x{5D2A}\x{5D2C}\x{5D2D}\x{5D2E}\x{5D30}\x{5D31}\x{5D32}\x{5D33}\x{5D34}' - . '\x{5D35}\x{5D36}\x{5D37}\x{5D38}\x{5D39}\x{5D3A}\x{5D3C}\x{5D3D}\x{5D3E}' - . '\x{5D3F}\x{5D40}\x{5D41}\x{5D42}\x{5D43}\x{5D44}\x{5D45}\x{5D46}\x{5D47}' - . '\x{5D48}\x{5D49}\x{5D4A}\x{5D4B}\x{5D4C}\x{5D4D}\x{5D4E}\x{5D4F}\x{5D50}' - . '\x{5D51}\x{5D52}\x{5D54}\x{5D55}\x{5D56}\x{5D58}\x{5D59}\x{5D5A}\x{5D5B}' - . '\x{5D5D}\x{5D5E}\x{5D5F}\x{5D61}\x{5D62}\x{5D63}\x{5D64}\x{5D65}\x{5D66}' - . '\x{5D67}\x{5D68}\x{5D69}\x{5D6A}\x{5D6B}\x{5D6C}\x{5D6D}\x{5D6E}\x{5D6F}' - . '\x{5D70}\x{5D71}\x{5D72}\x{5D73}\x{5D74}\x{5D75}\x{5D76}\x{5D77}\x{5D78}' - . '\x{5D79}\x{5D7A}\x{5D7B}\x{5D7C}\x{5D7D}\x{5D7E}\x{5D7F}\x{5D80}\x{5D81}' - . '\x{5D82}\x{5D84}\x{5D85}\x{5D86}\x{5D87}\x{5D88}\x{5D89}\x{5D8A}\x{5D8B}' - . '\x{5D8C}\x{5D8D}\x{5D8E}\x{5D8F}\x{5D90}\x{5D91}\x{5D92}\x{5D93}\x{5D94}' - . '\x{5D95}\x{5D97}\x{5D98}\x{5D99}\x{5D9A}\x{5D9B}\x{5D9C}\x{5D9D}\x{5D9E}' - . '\x{5D9F}\x{5DA0}\x{5DA1}\x{5DA2}\x{5DA5}\x{5DA6}\x{5DA7}\x{5DA8}\x{5DA9}' - . '\x{5DAA}\x{5DAC}\x{5DAD}\x{5DAE}\x{5DAF}\x{5DB0}\x{5DB1}\x{5DB2}\x{5DB4}' - . '\x{5DB5}\x{5DB6}\x{5DB7}\x{5DB8}\x{5DBA}\x{5DBB}\x{5DBC}\x{5DBD}\x{5DBE}' - . '\x{5DBF}\x{5DC0}\x{5DC1}\x{5DC2}\x{5DC3}\x{5DC5}\x{5DC6}\x{5DC7}\x{5DC8}' - . '\x{5DC9}\x{5DCA}\x{5DCB}\x{5DCC}\x{5DCD}\x{5DCE}\x{5DCF}\x{5DD0}\x{5DD1}' - . '\x{5DD2}\x{5DD3}\x{5DD4}\x{5DD5}\x{5DD6}\x{5DD8}\x{5DD9}\x{5DDB}\x{5DDD}' - . '\x{5DDE}\x{5DDF}\x{5DE0}\x{5DE1}\x{5DE2}\x{5DE3}\x{5DE4}\x{5DE5}\x{5DE6}' - . '\x{5DE7}\x{5DE8}\x{5DE9}\x{5DEA}\x{5DEB}\x{5DEC}\x{5DED}\x{5DEE}\x{5DEF}' - . '\x{5DF0}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DF8}\x{5DF9}' - . '\x{5DFA}\x{5DFB}\x{5DFC}\x{5DFD}\x{5DFE}\x{5DFF}\x{5E00}\x{5E01}\x{5E02}' - . '\x{5E03}\x{5E04}\x{5E05}\x{5E06}\x{5E07}\x{5E08}\x{5E09}\x{5E0A}\x{5E0B}' - . '\x{5E0C}\x{5E0D}\x{5E0E}\x{5E0F}\x{5E10}\x{5E11}\x{5E13}\x{5E14}\x{5E15}' - . '\x{5E16}\x{5E17}\x{5E18}\x{5E19}\x{5E1A}\x{5E1B}\x{5E1C}\x{5E1D}\x{5E1E}' - . '\x{5E1F}\x{5E20}\x{5E21}\x{5E22}\x{5E23}\x{5E24}\x{5E25}\x{5E26}\x{5E27}' - . '\x{5E28}\x{5E29}\x{5E2A}\x{5E2B}\x{5E2C}\x{5E2D}\x{5E2E}\x{5E2F}\x{5E30}' - . '\x{5E31}\x{5E32}\x{5E33}\x{5E34}\x{5E35}\x{5E36}\x{5E37}\x{5E38}\x{5E39}' - . '\x{5E3A}\x{5E3B}\x{5E3C}\x{5E3D}\x{5E3E}\x{5E40}\x{5E41}\x{5E42}\x{5E43}' - . '\x{5E44}\x{5E45}\x{5E46}\x{5E47}\x{5E49}\x{5E4A}\x{5E4B}\x{5E4C}\x{5E4D}' - . '\x{5E4E}\x{5E4F}\x{5E50}\x{5E52}\x{5E53}\x{5E54}\x{5E55}\x{5E56}\x{5E57}' - . '\x{5E58}\x{5E59}\x{5E5A}\x{5E5B}\x{5E5C}\x{5E5D}\x{5E5E}\x{5E5F}\x{5E60}' - . '\x{5E61}\x{5E62}\x{5E63}\x{5E64}\x{5E65}\x{5E66}\x{5E67}\x{5E68}\x{5E69}' - . '\x{5E6A}\x{5E6B}\x{5E6C}\x{5E6D}\x{5E6E}\x{5E6F}\x{5E70}\x{5E71}\x{5E72}' - . '\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E77}\x{5E78}\x{5E79}\x{5E7A}\x{5E7B}' - . '\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E80}\x{5E81}\x{5E82}\x{5E83}\x{5E84}' - . '\x{5E85}\x{5E86}\x{5E87}\x{5E88}\x{5E89}\x{5E8A}\x{5E8B}\x{5E8C}\x{5E8D}' - . '\x{5E8E}\x{5E8F}\x{5E90}\x{5E91}\x{5E93}\x{5E94}\x{5E95}\x{5E96}\x{5E97}' - . '\x{5E98}\x{5E99}\x{5E9A}\x{5E9B}\x{5E9C}\x{5E9D}\x{5E9E}\x{5E9F}\x{5EA0}' - . '\x{5EA1}\x{5EA2}\x{5EA3}\x{5EA4}\x{5EA5}\x{5EA6}\x{5EA7}\x{5EA8}\x{5EA9}' - . '\x{5EAA}\x{5EAB}\x{5EAC}\x{5EAD}\x{5EAE}\x{5EAF}\x{5EB0}\x{5EB1}\x{5EB2}' - . '\x{5EB3}\x{5EB4}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EB9}\x{5EBB}\x{5EBC}' - . '\x{5EBD}\x{5EBE}\x{5EBF}\x{5EC1}\x{5EC2}\x{5EC3}\x{5EC4}\x{5EC5}\x{5EC6}' - . '\x{5EC7}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECB}\x{5ECC}\x{5ECD}\x{5ECE}\x{5ECF}' - . '\x{5ED0}\x{5ED1}\x{5ED2}\x{5ED3}\x{5ED4}\x{5ED5}\x{5ED6}\x{5ED7}\x{5ED8}' - . '\x{5ED9}\x{5EDA}\x{5EDB}\x{5EDC}\x{5EDD}\x{5EDE}\x{5EDF}\x{5EE0}\x{5EE1}' - . '\x{5EE2}\x{5EE3}\x{5EE4}\x{5EE5}\x{5EE6}\x{5EE7}\x{5EE8}\x{5EE9}\x{5EEA}' - . '\x{5EEC}\x{5EED}\x{5EEE}\x{5EEF}\x{5EF0}\x{5EF1}\x{5EF2}\x{5EF3}\x{5EF4}' - . '\x{5EF5}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}\x{5EFB}\x{5EFC}\x{5EFD}\x{5EFE}' - . '\x{5EFF}\x{5F00}\x{5F01}\x{5F02}\x{5F03}\x{5F04}\x{5F05}\x{5F06}\x{5F07}' - . '\x{5F08}\x{5F0A}\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F11}\x{5F12}\x{5F13}' - . '\x{5F14}\x{5F15}\x{5F16}\x{5F17}\x{5F18}\x{5F19}\x{5F1A}\x{5F1B}\x{5F1C}' - . '\x{5F1D}\x{5F1E}\x{5F1F}\x{5F20}\x{5F21}\x{5F22}\x{5F23}\x{5F24}\x{5F25}' - . '\x{5F26}\x{5F27}\x{5F28}\x{5F29}\x{5F2A}\x{5F2B}\x{5F2C}\x{5F2D}\x{5F2E}' - . '\x{5F2F}\x{5F30}\x{5F31}\x{5F32}\x{5F33}\x{5F34}\x{5F35}\x{5F36}\x{5F37}' - . '\x{5F38}\x{5F39}\x{5F3A}\x{5F3C}\x{5F3E}\x{5F3F}\x{5F40}\x{5F41}\x{5F42}' - . '\x{5F43}\x{5F44}\x{5F45}\x{5F46}\x{5F47}\x{5F48}\x{5F49}\x{5F4A}\x{5F4B}' - . '\x{5F4C}\x{5F4D}\x{5F4E}\x{5F4F}\x{5F50}\x{5F51}\x{5F52}\x{5F53}\x{5F54}' - . '\x{5F55}\x{5F56}\x{5F57}\x{5F58}\x{5F59}\x{5F5A}\x{5F5B}\x{5F5C}\x{5F5D}' - . '\x{5F5E}\x{5F5F}\x{5F60}\x{5F61}\x{5F62}\x{5F63}\x{5F64}\x{5F65}\x{5F66}' - . '\x{5F67}\x{5F68}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}\x{5F6D}\x{5F6E}\x{5F6F}' - . '\x{5F70}\x{5F71}\x{5F72}\x{5F73}\x{5F74}\x{5F75}\x{5F76}\x{5F77}\x{5F78}' - . '\x{5F79}\x{5F7A}\x{5F7B}\x{5F7C}\x{5F7D}\x{5F7E}\x{5F7F}\x{5F80}\x{5F81}' - . '\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F86}\x{5F87}\x{5F88}\x{5F89}\x{5F8A}' - . '\x{5F8B}\x{5F8C}\x{5F8D}\x{5F8E}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F94}' - . '\x{5F95}\x{5F96}\x{5F97}\x{5F98}\x{5F99}\x{5F9B}\x{5F9C}\x{5F9D}\x{5F9E}' - . '\x{5F9F}\x{5FA0}\x{5FA1}\x{5FA2}\x{5FA5}\x{5FA6}\x{5FA7}\x{5FA8}\x{5FA9}' - . '\x{5FAA}\x{5FAB}\x{5FAC}\x{5FAD}\x{5FAE}\x{5FAF}\x{5FB1}\x{5FB2}\x{5FB3}' - . '\x{5FB4}\x{5FB5}\x{5FB6}\x{5FB7}\x{5FB8}\x{5FB9}\x{5FBA}\x{5FBB}\x{5FBC}' - . '\x{5FBD}\x{5FBE}\x{5FBF}\x{5FC0}\x{5FC1}\x{5FC3}\x{5FC4}\x{5FC5}\x{5FC6}' - . '\x{5FC7}\x{5FC8}\x{5FC9}\x{5FCA}\x{5FCB}\x{5FCC}\x{5FCD}\x{5FCF}\x{5FD0}' - . '\x{5FD1}\x{5FD2}\x{5FD3}\x{5FD4}\x{5FD5}\x{5FD6}\x{5FD7}\x{5FD8}\x{5FD9}' - . '\x{5FDA}\x{5FDC}\x{5FDD}\x{5FDE}\x{5FE0}\x{5FE1}\x{5FE3}\x{5FE4}\x{5FE5}' - . '\x{5FE6}\x{5FE7}\x{5FE8}\x{5FE9}\x{5FEA}\x{5FEB}\x{5FED}\x{5FEE}\x{5FEF}' - . '\x{5FF0}\x{5FF1}\x{5FF2}\x{5FF3}\x{5FF4}\x{5FF5}\x{5FF6}\x{5FF7}\x{5FF8}' - . '\x{5FF9}\x{5FFA}\x{5FFB}\x{5FFD}\x{5FFE}\x{5FFF}\x{6000}\x{6001}\x{6002}' - . '\x{6003}\x{6004}\x{6005}\x{6006}\x{6007}\x{6008}\x{6009}\x{600A}\x{600B}' - . '\x{600C}\x{600D}\x{600E}\x{600F}\x{6010}\x{6011}\x{6012}\x{6013}\x{6014}' - . '\x{6015}\x{6016}\x{6017}\x{6018}\x{6019}\x{601A}\x{601B}\x{601C}\x{601D}' - . '\x{601E}\x{601F}\x{6020}\x{6021}\x{6022}\x{6024}\x{6025}\x{6026}\x{6027}' - . '\x{6028}\x{6029}\x{602A}\x{602B}\x{602C}\x{602D}\x{602E}\x{602F}\x{6030}' - . '\x{6031}\x{6032}\x{6033}\x{6034}\x{6035}\x{6036}\x{6037}\x{6038}\x{6039}' - . '\x{603A}\x{603B}\x{603C}\x{603D}\x{603E}\x{603F}\x{6040}\x{6041}\x{6042}' - . '\x{6043}\x{6044}\x{6045}\x{6046}\x{6047}\x{6048}\x{6049}\x{604A}\x{604B}' - . '\x{604C}\x{604D}\x{604E}\x{604F}\x{6050}\x{6051}\x{6052}\x{6053}\x{6054}' - . '\x{6055}\x{6057}\x{6058}\x{6059}\x{605A}\x{605B}\x{605C}\x{605D}\x{605E}' - . '\x{605F}\x{6062}\x{6063}\x{6064}\x{6065}\x{6066}\x{6067}\x{6068}\x{6069}' - . '\x{606A}\x{606B}\x{606C}\x{606D}\x{606E}\x{606F}\x{6070}\x{6072}\x{6073}' - . '\x{6075}\x{6076}\x{6077}\x{6078}\x{6079}\x{607A}\x{607B}\x{607C}\x{607D}' - . '\x{607E}\x{607F}\x{6080}\x{6081}\x{6082}\x{6083}\x{6084}\x{6085}\x{6086}' - . '\x{6087}\x{6088}\x{6089}\x{608A}\x{608B}\x{608C}\x{608D}\x{608E}\x{608F}' - . '\x{6090}\x{6092}\x{6094}\x{6095}\x{6096}\x{6097}\x{6098}\x{6099}\x{609A}' - . '\x{609B}\x{609C}\x{609D}\x{609E}\x{609F}\x{60A0}\x{60A1}\x{60A2}\x{60A3}' - . '\x{60A4}\x{60A6}\x{60A7}\x{60A8}\x{60AA}\x{60AB}\x{60AC}\x{60AD}\x{60AE}' - . '\x{60AF}\x{60B0}\x{60B1}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B7}' - . '\x{60B8}\x{60B9}\x{60BA}\x{60BB}\x{60BC}\x{60BD}\x{60BE}\x{60BF}\x{60C0}' - . '\x{60C1}\x{60C2}\x{60C3}\x{60C4}\x{60C5}\x{60C6}\x{60C7}\x{60C8}\x{60C9}' - . '\x{60CA}\x{60CB}\x{60CC}\x{60CD}\x{60CE}\x{60CF}\x{60D0}\x{60D1}\x{60D3}' - . '\x{60D4}\x{60D5}\x{60D7}\x{60D8}\x{60D9}\x{60DA}\x{60DB}\x{60DC}\x{60DD}' - . '\x{60DF}\x{60E0}\x{60E1}\x{60E2}\x{60E4}\x{60E6}\x{60E7}\x{60E8}\x{60E9}' - . '\x{60EA}\x{60EB}\x{60EC}\x{60ED}\x{60EE}\x{60EF}\x{60F0}\x{60F1}\x{60F2}' - . '\x{60F3}\x{60F4}\x{60F5}\x{60F6}\x{60F7}\x{60F8}\x{60F9}\x{60FA}\x{60FB}' - . '\x{60FC}\x{60FE}\x{60FF}\x{6100}\x{6101}\x{6103}\x{6104}\x{6105}\x{6106}' - . '\x{6108}\x{6109}\x{610A}\x{610B}\x{610C}\x{610D}\x{610E}\x{610F}\x{6110}' - . '\x{6112}\x{6113}\x{6114}\x{6115}\x{6116}\x{6117}\x{6118}\x{6119}\x{611A}' - . '\x{611B}\x{611C}\x{611D}\x{611F}\x{6120}\x{6122}\x{6123}\x{6124}\x{6125}' - . '\x{6126}\x{6127}\x{6128}\x{6129}\x{612A}\x{612B}\x{612C}\x{612D}\x{612E}' - . '\x{612F}\x{6130}\x{6132}\x{6134}\x{6136}\x{6137}\x{613A}\x{613B}\x{613C}' - . '\x{613D}\x{613E}\x{613F}\x{6140}\x{6141}\x{6142}\x{6143}\x{6144}\x{6145}' - . '\x{6146}\x{6147}\x{6148}\x{6149}\x{614A}\x{614B}\x{614C}\x{614D}\x{614E}' - . '\x{614F}\x{6150}\x{6151}\x{6152}\x{6153}\x{6154}\x{6155}\x{6156}\x{6157}' - . '\x{6158}\x{6159}\x{615A}\x{615B}\x{615C}\x{615D}\x{615E}\x{615F}\x{6161}' - . '\x{6162}\x{6163}\x{6164}\x{6165}\x{6166}\x{6167}\x{6168}\x{6169}\x{616A}' - . '\x{616B}\x{616C}\x{616D}\x{616E}\x{6170}\x{6171}\x{6172}\x{6173}\x{6174}' - . '\x{6175}\x{6176}\x{6177}\x{6178}\x{6179}\x{617A}\x{617C}\x{617E}\x{6180}' - . '\x{6181}\x{6182}\x{6183}\x{6184}\x{6185}\x{6187}\x{6188}\x{6189}\x{618A}' - . '\x{618B}\x{618C}\x{618D}\x{618E}\x{618F}\x{6190}\x{6191}\x{6192}\x{6193}' - . '\x{6194}\x{6195}\x{6196}\x{6198}\x{6199}\x{619A}\x{619B}\x{619D}\x{619E}' - . '\x{619F}\x{61A0}\x{61A1}\x{61A2}\x{61A3}\x{61A4}\x{61A5}\x{61A6}\x{61A7}' - . '\x{61A8}\x{61A9}\x{61AA}\x{61AB}\x{61AC}\x{61AD}\x{61AE}\x{61AF}\x{61B0}' - . '\x{61B1}\x{61B2}\x{61B3}\x{61B4}\x{61B5}\x{61B6}\x{61B7}\x{61B8}\x{61BA}' - . '\x{61BC}\x{61BD}\x{61BE}\x{61BF}\x{61C0}\x{61C1}\x{61C2}\x{61C3}\x{61C4}' - . '\x{61C5}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' - . '\x{61CE}\x{61CF}\x{61D0}\x{61D1}\x{61D2}\x{61D4}\x{61D6}\x{61D7}\x{61D8}' - . '\x{61D9}\x{61DA}\x{61DB}\x{61DC}\x{61DD}\x{61DE}\x{61DF}\x{61E0}\x{61E1}' - . '\x{61E2}\x{61E3}\x{61E4}\x{61E5}\x{61E6}\x{61E7}\x{61E8}\x{61E9}\x{61EA}' - . '\x{61EB}\x{61ED}\x{61EE}\x{61F0}\x{61F1}\x{61F2}\x{61F3}\x{61F5}\x{61F6}' - . '\x{61F7}\x{61F8}\x{61F9}\x{61FA}\x{61FB}\x{61FC}\x{61FD}\x{61FE}\x{61FF}' - . '\x{6200}\x{6201}\x{6202}\x{6203}\x{6204}\x{6206}\x{6207}\x{6208}\x{6209}' - . '\x{620A}\x{620B}\x{620C}\x{620D}\x{620E}\x{620F}\x{6210}\x{6211}\x{6212}' - . '\x{6213}\x{6214}\x{6215}\x{6216}\x{6217}\x{6218}\x{6219}\x{621A}\x{621B}' - . '\x{621C}\x{621D}\x{621E}\x{621F}\x{6220}\x{6221}\x{6222}\x{6223}\x{6224}' - . '\x{6225}\x{6226}\x{6227}\x{6228}\x{6229}\x{622A}\x{622B}\x{622C}\x{622D}' - . '\x{622E}\x{622F}\x{6230}\x{6231}\x{6232}\x{6233}\x{6234}\x{6236}\x{6237}' - . '\x{6238}\x{623A}\x{623B}\x{623C}\x{623D}\x{623E}\x{623F}\x{6240}\x{6241}' - . '\x{6242}\x{6243}\x{6244}\x{6245}\x{6246}\x{6247}\x{6248}\x{6249}\x{624A}' - . '\x{624B}\x{624C}\x{624D}\x{624E}\x{624F}\x{6250}\x{6251}\x{6252}\x{6253}' - . '\x{6254}\x{6255}\x{6256}\x{6258}\x{6259}\x{625A}\x{625B}\x{625C}\x{625D}' - . '\x{625E}\x{625F}\x{6260}\x{6261}\x{6262}\x{6263}\x{6264}\x{6265}\x{6266}' - . '\x{6267}\x{6268}\x{6269}\x{626A}\x{626B}\x{626C}\x{626D}\x{626E}\x{626F}' - . '\x{6270}\x{6271}\x{6272}\x{6273}\x{6274}\x{6275}\x{6276}\x{6277}\x{6278}' - . '\x{6279}\x{627A}\x{627B}\x{627C}\x{627D}\x{627E}\x{627F}\x{6280}\x{6281}' - . '\x{6283}\x{6284}\x{6285}\x{6286}\x{6287}\x{6288}\x{6289}\x{628A}\x{628B}' - . '\x{628C}\x{628E}\x{628F}\x{6290}\x{6291}\x{6292}\x{6293}\x{6294}\x{6295}' - . '\x{6296}\x{6297}\x{6298}\x{6299}\x{629A}\x{629B}\x{629C}\x{629E}\x{629F}' - . '\x{62A0}\x{62A1}\x{62A2}\x{62A3}\x{62A4}\x{62A5}\x{62A7}\x{62A8}\x{62A9}' - . '\x{62AA}\x{62AB}\x{62AC}\x{62AD}\x{62AE}\x{62AF}\x{62B0}\x{62B1}\x{62B2}' - . '\x{62B3}\x{62B4}\x{62B5}\x{62B6}\x{62B7}\x{62B8}\x{62B9}\x{62BA}\x{62BB}' - . '\x{62BC}\x{62BD}\x{62BE}\x{62BF}\x{62C0}\x{62C1}\x{62C2}\x{62C3}\x{62C4}' - . '\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CB}\x{62CC}\x{62CD}' - . '\x{62CE}\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D5}\x{62D6}' - . '\x{62D7}\x{62D8}\x{62D9}\x{62DA}\x{62DB}\x{62DC}\x{62DD}\x{62DF}\x{62E0}' - . '\x{62E1}\x{62E2}\x{62E3}\x{62E4}\x{62E5}\x{62E6}\x{62E7}\x{62E8}\x{62E9}' - . '\x{62EB}\x{62EC}\x{62ED}\x{62EE}\x{62EF}\x{62F0}\x{62F1}\x{62F2}\x{62F3}' - . '\x{62F4}\x{62F5}\x{62F6}\x{62F7}\x{62F8}\x{62F9}\x{62FA}\x{62FB}\x{62FC}' - . '\x{62FD}\x{62FE}\x{62FF}\x{6300}\x{6301}\x{6302}\x{6303}\x{6304}\x{6305}' - . '\x{6306}\x{6307}\x{6308}\x{6309}\x{630B}\x{630C}\x{630D}\x{630E}\x{630F}' - . '\x{6310}\x{6311}\x{6312}\x{6313}\x{6314}\x{6315}\x{6316}\x{6318}\x{6319}' - . '\x{631A}\x{631B}\x{631C}\x{631D}\x{631E}\x{631F}\x{6320}\x{6321}\x{6322}' - . '\x{6323}\x{6324}\x{6325}\x{6326}\x{6327}\x{6328}\x{6329}\x{632A}\x{632B}' - . '\x{632C}\x{632D}\x{632E}\x{632F}\x{6330}\x{6332}\x{6333}\x{6334}\x{6336}' - . '\x{6338}\x{6339}\x{633A}\x{633B}\x{633C}\x{633D}\x{633E}\x{6340}\x{6341}' - . '\x{6342}\x{6343}\x{6344}\x{6345}\x{6346}\x{6347}\x{6348}\x{6349}\x{634A}' - . '\x{634B}\x{634C}\x{634D}\x{634E}\x{634F}\x{6350}\x{6351}\x{6352}\x{6353}' - . '\x{6354}\x{6355}\x{6356}\x{6357}\x{6358}\x{6359}\x{635A}\x{635C}\x{635D}' - . '\x{635E}\x{635F}\x{6360}\x{6361}\x{6362}\x{6363}\x{6364}\x{6365}\x{6366}' - . '\x{6367}\x{6368}\x{6369}\x{636A}\x{636B}\x{636C}\x{636D}\x{636E}\x{636F}' - . '\x{6370}\x{6371}\x{6372}\x{6373}\x{6374}\x{6375}\x{6376}\x{6377}\x{6378}' - . '\x{6379}\x{637A}\x{637B}\x{637C}\x{637D}\x{637E}\x{6380}\x{6381}\x{6382}' - . '\x{6383}\x{6384}\x{6385}\x{6386}\x{6387}\x{6388}\x{6389}\x{638A}\x{638C}' - . '\x{638D}\x{638E}\x{638F}\x{6390}\x{6391}\x{6392}\x{6394}\x{6395}\x{6396}' - . '\x{6397}\x{6398}\x{6399}\x{639A}\x{639B}\x{639C}\x{639D}\x{639E}\x{639F}' - . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A4}\x{63A5}\x{63A6}\x{63A7}\x{63A8}' - . '\x{63A9}\x{63AA}\x{63AB}\x{63AC}\x{63AD}\x{63AE}\x{63AF}\x{63B0}\x{63B1}' - . '\x{63B2}\x{63B3}\x{63B4}\x{63B5}\x{63B6}\x{63B7}\x{63B8}\x{63B9}\x{63BA}' - . '\x{63BC}\x{63BD}\x{63BE}\x{63BF}\x{63C0}\x{63C1}\x{63C2}\x{63C3}\x{63C4}' - . '\x{63C5}\x{63C6}\x{63C7}\x{63C8}\x{63C9}\x{63CA}\x{63CB}\x{63CC}\x{63CD}' - . '\x{63CE}\x{63CF}\x{63D0}\x{63D2}\x{63D3}\x{63D4}\x{63D5}\x{63D6}\x{63D7}' - . '\x{63D8}\x{63D9}\x{63DA}\x{63DB}\x{63DC}\x{63DD}\x{63DE}\x{63DF}\x{63E0}' - . '\x{63E1}\x{63E2}\x{63E3}\x{63E4}\x{63E5}\x{63E6}\x{63E7}\x{63E8}\x{63E9}' - . '\x{63EA}\x{63EB}\x{63EC}\x{63ED}\x{63EE}\x{63EF}\x{63F0}\x{63F1}\x{63F2}' - . '\x{63F3}\x{63F4}\x{63F5}\x{63F6}\x{63F7}\x{63F8}\x{63F9}\x{63FA}\x{63FB}' - . '\x{63FC}\x{63FD}\x{63FE}\x{63FF}\x{6400}\x{6401}\x{6402}\x{6403}\x{6404}' - . '\x{6405}\x{6406}\x{6408}\x{6409}\x{640A}\x{640B}\x{640C}\x{640D}\x{640E}' - . '\x{640F}\x{6410}\x{6411}\x{6412}\x{6413}\x{6414}\x{6415}\x{6416}\x{6417}' - . '\x{6418}\x{6419}\x{641A}\x{641B}\x{641C}\x{641D}\x{641E}\x{641F}\x{6420}' - . '\x{6421}\x{6422}\x{6423}\x{6424}\x{6425}\x{6426}\x{6427}\x{6428}\x{6429}' - . '\x{642A}\x{642B}\x{642C}\x{642D}\x{642E}\x{642F}\x{6430}\x{6431}\x{6432}' - . '\x{6433}\x{6434}\x{6435}\x{6436}\x{6437}\x{6438}\x{6439}\x{643A}\x{643D}' - . '\x{643E}\x{643F}\x{6440}\x{6441}\x{6443}\x{6444}\x{6445}\x{6446}\x{6447}' - . '\x{6448}\x{644A}\x{644B}\x{644C}\x{644D}\x{644E}\x{644F}\x{6450}\x{6451}' - . '\x{6452}\x{6453}\x{6454}\x{6455}\x{6456}\x{6457}\x{6458}\x{6459}\x{645B}' - . '\x{645C}\x{645D}\x{645E}\x{645F}\x{6460}\x{6461}\x{6462}\x{6463}\x{6464}' - . '\x{6465}\x{6466}\x{6467}\x{6468}\x{6469}\x{646A}\x{646B}\x{646C}\x{646D}' - . '\x{646E}\x{646F}\x{6470}\x{6471}\x{6472}\x{6473}\x{6474}\x{6475}\x{6476}' - . '\x{6477}\x{6478}\x{6479}\x{647A}\x{647B}\x{647C}\x{647D}\x{647F}\x{6480}' - . '\x{6481}\x{6482}\x{6483}\x{6484}\x{6485}\x{6487}\x{6488}\x{6489}\x{648A}' - . '\x{648B}\x{648C}\x{648D}\x{648E}\x{648F}\x{6490}\x{6491}\x{6492}\x{6493}' - . '\x{6494}\x{6495}\x{6496}\x{6497}\x{6498}\x{6499}\x{649A}\x{649B}\x{649C}' - . '\x{649D}\x{649E}\x{649F}\x{64A0}\x{64A2}\x{64A3}\x{64A4}\x{64A5}\x{64A6}' - . '\x{64A7}\x{64A8}\x{64A9}\x{64AA}\x{64AB}\x{64AC}\x{64AD}\x{64AE}\x{64B0}' - . '\x{64B1}\x{64B2}\x{64B3}\x{64B4}\x{64B5}\x{64B7}\x{64B8}\x{64B9}\x{64BA}' - . '\x{64BB}\x{64BC}\x{64BD}\x{64BE}\x{64BF}\x{64C0}\x{64C1}\x{64C2}\x{64C3}' - . '\x{64C4}\x{64C5}\x{64C6}\x{64C7}\x{64C9}\x{64CA}\x{64CB}\x{64CC}\x{64CD}' - . '\x{64CE}\x{64CF}\x{64D0}\x{64D1}\x{64D2}\x{64D3}\x{64D4}\x{64D6}\x{64D7}' - . '\x{64D8}\x{64D9}\x{64DA}\x{64DB}\x{64DC}\x{64DD}\x{64DE}\x{64DF}\x{64E0}' - . '\x{64E2}\x{64E3}\x{64E4}\x{64E6}\x{64E7}\x{64E8}\x{64E9}\x{64EA}\x{64EB}' - . '\x{64EC}\x{64ED}\x{64EF}\x{64F0}\x{64F1}\x{64F2}\x{64F3}\x{64F4}\x{64F6}' - . '\x{64F7}\x{64F8}\x{64FA}\x{64FB}\x{64FC}\x{64FD}\x{64FE}\x{64FF}\x{6500}' - . '\x{6501}\x{6503}\x{6504}\x{6505}\x{6506}\x{6507}\x{6508}\x{6509}\x{650B}' - . '\x{650C}\x{650D}\x{650E}\x{650F}\x{6510}\x{6511}\x{6512}\x{6513}\x{6514}' - . '\x{6515}\x{6516}\x{6517}\x{6518}\x{6519}\x{651A}\x{651B}\x{651C}\x{651D}' - . '\x{651E}\x{6520}\x{6521}\x{6522}\x{6523}\x{6524}\x{6525}\x{6526}\x{6527}' - . '\x{6529}\x{652A}\x{652B}\x{652C}\x{652D}\x{652E}\x{652F}\x{6530}\x{6531}' - . '\x{6532}\x{6533}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}\x{653A}' - . '\x{653B}\x{653C}\x{653D}\x{653E}\x{653F}\x{6541}\x{6543}\x{6544}\x{6545}' - . '\x{6546}\x{6547}\x{6548}\x{6549}\x{654A}\x{654B}\x{654C}\x{654D}\x{654E}' - . '\x{654F}\x{6550}\x{6551}\x{6552}\x{6553}\x{6554}\x{6555}\x{6556}\x{6557}' - . '\x{6558}\x{6559}\x{655B}\x{655C}\x{655D}\x{655E}\x{6560}\x{6561}\x{6562}' - . '\x{6563}\x{6564}\x{6565}\x{6566}\x{6567}\x{6568}\x{6569}\x{656A}\x{656B}' - . '\x{656C}\x{656E}\x{656F}\x{6570}\x{6571}\x{6572}\x{6573}\x{6574}\x{6575}' - . '\x{6576}\x{6577}\x{6578}\x{6579}\x{657A}\x{657B}\x{657C}\x{657E}\x{657F}' - . '\x{6580}\x{6581}\x{6582}\x{6583}\x{6584}\x{6585}\x{6586}\x{6587}\x{6588}' - . '\x{6589}\x{658B}\x{658C}\x{658D}\x{658E}\x{658F}\x{6590}\x{6591}\x{6592}' - . '\x{6593}\x{6594}\x{6595}\x{6596}\x{6597}\x{6598}\x{6599}\x{659B}\x{659C}' - . '\x{659D}\x{659E}\x{659F}\x{65A0}\x{65A1}\x{65A2}\x{65A3}\x{65A4}\x{65A5}' - . '\x{65A6}\x{65A7}\x{65A8}\x{65A9}\x{65AA}\x{65AB}\x{65AC}\x{65AD}\x{65AE}' - . '\x{65AF}\x{65B0}\x{65B1}\x{65B2}\x{65B3}\x{65B4}\x{65B6}\x{65B7}\x{65B8}' - . '\x{65B9}\x{65BA}\x{65BB}\x{65BC}\x{65BD}\x{65BF}\x{65C0}\x{65C1}\x{65C2}' - . '\x{65C3}\x{65C4}\x{65C5}\x{65C6}\x{65C7}\x{65CA}\x{65CB}\x{65CC}\x{65CD}' - . '\x{65CE}\x{65CF}\x{65D0}\x{65D2}\x{65D3}\x{65D4}\x{65D5}\x{65D6}\x{65D7}' - . '\x{65DA}\x{65DB}\x{65DD}\x{65DE}\x{65DF}\x{65E0}\x{65E1}\x{65E2}\x{65E3}' - . '\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}\x{65EB}\x{65EC}\x{65ED}\x{65EE}' - . '\x{65EF}\x{65F0}\x{65F1}\x{65F2}\x{65F3}\x{65F4}\x{65F5}\x{65F6}\x{65F7}' - . '\x{65F8}\x{65FA}\x{65FB}\x{65FC}\x{65FD}\x{6600}\x{6601}\x{6602}\x{6603}' - . '\x{6604}\x{6605}\x{6606}\x{6607}\x{6608}\x{6609}\x{660A}\x{660B}\x{660C}' - . '\x{660D}\x{660E}\x{660F}\x{6610}\x{6611}\x{6612}\x{6613}\x{6614}\x{6615}' - . '\x{6616}\x{6618}\x{6619}\x{661A}\x{661B}\x{661C}\x{661D}\x{661F}\x{6620}' - . '\x{6621}\x{6622}\x{6623}\x{6624}\x{6625}\x{6626}\x{6627}\x{6628}\x{6629}' - . '\x{662A}\x{662B}\x{662D}\x{662E}\x{662F}\x{6630}\x{6631}\x{6632}\x{6633}' - . '\x{6634}\x{6635}\x{6636}\x{6639}\x{663A}\x{663C}\x{663D}\x{663E}\x{6640}' - . '\x{6641}\x{6642}\x{6643}\x{6644}\x{6645}\x{6646}\x{6647}\x{6649}\x{664A}' - . '\x{664B}\x{664C}\x{664E}\x{664F}\x{6650}\x{6651}\x{6652}\x{6653}\x{6654}' - . '\x{6655}\x{6656}\x{6657}\x{6658}\x{6659}\x{665A}\x{665B}\x{665C}\x{665D}' - . '\x{665E}\x{665F}\x{6661}\x{6662}\x{6664}\x{6665}\x{6666}\x{6668}\x{6669}' - . '\x{666A}\x{666B}\x{666C}\x{666D}\x{666E}\x{666F}\x{6670}\x{6671}\x{6672}' - . '\x{6673}\x{6674}\x{6675}\x{6676}\x{6677}\x{6678}\x{6679}\x{667A}\x{667B}' - . '\x{667C}\x{667D}\x{667E}\x{667F}\x{6680}\x{6681}\x{6682}\x{6683}\x{6684}' - . '\x{6685}\x{6686}\x{6687}\x{6688}\x{6689}\x{668A}\x{668B}\x{668C}\x{668D}' - . '\x{668E}\x{668F}\x{6690}\x{6691}\x{6693}\x{6694}\x{6695}\x{6696}\x{6697}' - . '\x{6698}\x{6699}\x{669A}\x{669B}\x{669D}\x{669F}\x{66A0}\x{66A1}\x{66A2}' - . '\x{66A3}\x{66A4}\x{66A5}\x{66A6}\x{66A7}\x{66A8}\x{66A9}\x{66AA}\x{66AB}' - . '\x{66AE}\x{66AF}\x{66B0}\x{66B1}\x{66B2}\x{66B3}\x{66B4}\x{66B5}\x{66B6}' - . '\x{66B7}\x{66B8}\x{66B9}\x{66BA}\x{66BB}\x{66BC}\x{66BD}\x{66BE}\x{66BF}' - . '\x{66C0}\x{66C1}\x{66C2}\x{66C3}\x{66C4}\x{66C5}\x{66C6}\x{66C7}\x{66C8}' - . '\x{66C9}\x{66CA}\x{66CB}\x{66CC}\x{66CD}\x{66CE}\x{66CF}\x{66D1}\x{66D2}' - . '\x{66D4}\x{66D5}\x{66D6}\x{66D8}\x{66D9}\x{66DA}\x{66DB}\x{66DC}\x{66DD}' - . '\x{66DE}\x{66E0}\x{66E1}\x{66E2}\x{66E3}\x{66E4}\x{66E5}\x{66E6}\x{66E7}' - . '\x{66E8}\x{66E9}\x{66EA}\x{66EB}\x{66EC}\x{66ED}\x{66EE}\x{66F0}\x{66F1}' - . '\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F6}\x{66F7}\x{66F8}\x{66F9}\x{66FA}' - . '\x{66FB}\x{66FC}\x{66FE}\x{66FF}\x{6700}\x{6701}\x{6703}\x{6704}\x{6705}' - . '\x{6706}\x{6708}\x{6709}\x{670A}\x{670B}\x{670C}\x{670D}\x{670E}\x{670F}' - . '\x{6710}\x{6711}\x{6712}\x{6713}\x{6714}\x{6715}\x{6716}\x{6717}\x{6718}' - . '\x{671A}\x{671B}\x{671C}\x{671D}\x{671E}\x{671F}\x{6720}\x{6721}\x{6722}' - . '\x{6723}\x{6725}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}\x{672D}' - . '\x{672E}\x{672F}\x{6730}\x{6731}\x{6732}\x{6733}\x{6734}\x{6735}\x{6736}' - . '\x{6737}\x{6738}\x{6739}\x{673A}\x{673B}\x{673C}\x{673D}\x{673E}\x{673F}' - . '\x{6740}\x{6741}\x{6742}\x{6743}\x{6744}\x{6745}\x{6746}\x{6747}\x{6748}' - . '\x{6749}\x{674A}\x{674B}\x{674C}\x{674D}\x{674E}\x{674F}\x{6750}\x{6751}' - . '\x{6752}\x{6753}\x{6754}\x{6755}\x{6756}\x{6757}\x{6758}\x{6759}\x{675A}' - . '\x{675B}\x{675C}\x{675D}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' - . '\x{6764}\x{6765}\x{6766}\x{6768}\x{6769}\x{676A}\x{676B}\x{676C}\x{676D}' - . '\x{676E}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}\x{6774}\x{6775}\x{6776}' - . '\x{6777}\x{6778}\x{6779}\x{677A}\x{677B}\x{677C}\x{677D}\x{677E}\x{677F}' - . '\x{6780}\x{6781}\x{6782}\x{6783}\x{6784}\x{6785}\x{6786}\x{6787}\x{6789}' - . '\x{678A}\x{678B}\x{678C}\x{678D}\x{678E}\x{678F}\x{6790}\x{6791}\x{6792}' - . '\x{6793}\x{6794}\x{6795}\x{6797}\x{6798}\x{6799}\x{679A}\x{679B}\x{679C}' - . '\x{679D}\x{679E}\x{679F}\x{67A0}\x{67A1}\x{67A2}\x{67A3}\x{67A4}\x{67A5}' - . '\x{67A6}\x{67A7}\x{67A8}\x{67AA}\x{67AB}\x{67AC}\x{67AD}\x{67AE}\x{67AF}' - . '\x{67B0}\x{67B1}\x{67B2}\x{67B3}\x{67B4}\x{67B5}\x{67B6}\x{67B7}\x{67B8}' - . '\x{67B9}\x{67BA}\x{67BB}\x{67BC}\x{67BE}\x{67C0}\x{67C1}\x{67C2}\x{67C3}' - . '\x{67C4}\x{67C5}\x{67C6}\x{67C7}\x{67C8}\x{67C9}\x{67CA}\x{67CB}\x{67CC}' - . '\x{67CD}\x{67CE}\x{67CF}\x{67D0}\x{67D1}\x{67D2}\x{67D3}\x{67D4}\x{67D6}' - . '\x{67D8}\x{67D9}\x{67DA}\x{67DB}\x{67DC}\x{67DD}\x{67DE}\x{67DF}\x{67E0}' - . '\x{67E1}\x{67E2}\x{67E3}\x{67E4}\x{67E5}\x{67E6}\x{67E7}\x{67E8}\x{67E9}' - . '\x{67EA}\x{67EB}\x{67EC}\x{67ED}\x{67EE}\x{67EF}\x{67F0}\x{67F1}\x{67F2}' - . '\x{67F3}\x{67F4}\x{67F5}\x{67F6}\x{67F7}\x{67F8}\x{67FA}\x{67FB}\x{67FC}' - . '\x{67FD}\x{67FE}\x{67FF}\x{6800}\x{6802}\x{6803}\x{6804}\x{6805}\x{6806}' - . '\x{6807}\x{6808}\x{6809}\x{680A}\x{680B}\x{680C}\x{680D}\x{680E}\x{680F}' - . '\x{6810}\x{6811}\x{6812}\x{6813}\x{6814}\x{6816}\x{6817}\x{6818}\x{6819}' - . '\x{681A}\x{681B}\x{681C}\x{681D}\x{681F}\x{6820}\x{6821}\x{6822}\x{6823}' - . '\x{6824}\x{6825}\x{6826}\x{6828}\x{6829}\x{682A}\x{682B}\x{682C}\x{682D}' - . '\x{682E}\x{682F}\x{6831}\x{6832}\x{6833}\x{6834}\x{6835}\x{6836}\x{6837}' - . '\x{6838}\x{6839}\x{683A}\x{683B}\x{683C}\x{683D}\x{683E}\x{683F}\x{6840}' - . '\x{6841}\x{6842}\x{6843}\x{6844}\x{6845}\x{6846}\x{6847}\x{6848}\x{6849}' - . '\x{684A}\x{684B}\x{684C}\x{684D}\x{684E}\x{684F}\x{6850}\x{6851}\x{6852}' - . '\x{6853}\x{6854}\x{6855}\x{6856}\x{6857}\x{685B}\x{685D}\x{6860}\x{6861}' - . '\x{6862}\x{6863}\x{6864}\x{6865}\x{6866}\x{6867}\x{6868}\x{6869}\x{686A}' - . '\x{686B}\x{686C}\x{686D}\x{686E}\x{686F}\x{6870}\x{6871}\x{6872}\x{6873}' - . '\x{6874}\x{6875}\x{6876}\x{6877}\x{6878}\x{6879}\x{687B}\x{687C}\x{687D}' - . '\x{687E}\x{687F}\x{6880}\x{6881}\x{6882}\x{6883}\x{6884}\x{6885}\x{6886}' - . '\x{6887}\x{6888}\x{6889}\x{688A}\x{688B}\x{688C}\x{688D}\x{688E}\x{688F}' - . '\x{6890}\x{6891}\x{6892}\x{6893}\x{6894}\x{6896}\x{6897}\x{6898}\x{689A}' - . '\x{689B}\x{689C}\x{689D}\x{689E}\x{689F}\x{68A0}\x{68A1}\x{68A2}\x{68A3}' - . '\x{68A4}\x{68A6}\x{68A7}\x{68A8}\x{68A9}\x{68AA}\x{68AB}\x{68AC}\x{68AD}' - . '\x{68AE}\x{68AF}\x{68B0}\x{68B1}\x{68B2}\x{68B3}\x{68B4}\x{68B5}\x{68B6}' - . '\x{68B7}\x{68B9}\x{68BB}\x{68BC}\x{68BD}\x{68BE}\x{68BF}\x{68C0}\x{68C1}' - . '\x{68C2}\x{68C4}\x{68C6}\x{68C7}\x{68C8}\x{68C9}\x{68CA}\x{68CB}\x{68CC}' - . '\x{68CD}\x{68CE}\x{68CF}\x{68D0}\x{68D1}\x{68D2}\x{68D3}\x{68D4}\x{68D5}' - . '\x{68D6}\x{68D7}\x{68D8}\x{68DA}\x{68DB}\x{68DC}\x{68DD}\x{68DE}\x{68DF}' - . '\x{68E0}\x{68E1}\x{68E3}\x{68E4}\x{68E6}\x{68E7}\x{68E8}\x{68E9}\x{68EA}' - . '\x{68EB}\x{68EC}\x{68ED}\x{68EE}\x{68EF}\x{68F0}\x{68F1}\x{68F2}\x{68F3}' - . '\x{68F4}\x{68F5}\x{68F6}\x{68F7}\x{68F8}\x{68F9}\x{68FA}\x{68FB}\x{68FC}' - . '\x{68FD}\x{68FE}\x{68FF}\x{6901}\x{6902}\x{6903}\x{6904}\x{6905}\x{6906}' - . '\x{6907}\x{6908}\x{690A}\x{690B}\x{690C}\x{690D}\x{690E}\x{690F}\x{6910}' - . '\x{6911}\x{6912}\x{6913}\x{6914}\x{6915}\x{6916}\x{6917}\x{6918}\x{6919}' - . '\x{691A}\x{691B}\x{691C}\x{691D}\x{691E}\x{691F}\x{6920}\x{6921}\x{6922}' - . '\x{6923}\x{6924}\x{6925}\x{6926}\x{6927}\x{6928}\x{6929}\x{692A}\x{692B}' - . '\x{692C}\x{692D}\x{692E}\x{692F}\x{6930}\x{6931}\x{6932}\x{6933}\x{6934}' - . '\x{6935}\x{6936}\x{6937}\x{6938}\x{6939}\x{693A}\x{693B}\x{693C}\x{693D}' - . '\x{693F}\x{6940}\x{6941}\x{6942}\x{6943}\x{6944}\x{6945}\x{6946}\x{6947}' - . '\x{6948}\x{6949}\x{694A}\x{694B}\x{694C}\x{694E}\x{694F}\x{6950}\x{6951}' - . '\x{6952}\x{6953}\x{6954}\x{6955}\x{6956}\x{6957}\x{6958}\x{6959}\x{695A}' - . '\x{695B}\x{695C}\x{695D}\x{695E}\x{695F}\x{6960}\x{6961}\x{6962}\x{6963}' - . '\x{6964}\x{6965}\x{6966}\x{6967}\x{6968}\x{6969}\x{696A}\x{696B}\x{696C}' - . '\x{696D}\x{696E}\x{696F}\x{6970}\x{6971}\x{6972}\x{6973}\x{6974}\x{6975}' - . '\x{6976}\x{6977}\x{6978}\x{6979}\x{697A}\x{697B}\x{697C}\x{697D}\x{697E}' - . '\x{697F}\x{6980}\x{6981}\x{6982}\x{6983}\x{6984}\x{6985}\x{6986}\x{6987}' - . '\x{6988}\x{6989}\x{698A}\x{698B}\x{698C}\x{698D}\x{698E}\x{698F}\x{6990}' - . '\x{6991}\x{6992}\x{6993}\x{6994}\x{6995}\x{6996}\x{6997}\x{6998}\x{6999}' - . '\x{699A}\x{699B}\x{699C}\x{699D}\x{699E}\x{69A0}\x{69A1}\x{69A3}\x{69A4}' - . '\x{69A5}\x{69A6}\x{69A7}\x{69A8}\x{69A9}\x{69AA}\x{69AB}\x{69AC}\x{69AD}' - . '\x{69AE}\x{69AF}\x{69B0}\x{69B1}\x{69B2}\x{69B3}\x{69B4}\x{69B5}\x{69B6}' - . '\x{69B7}\x{69B8}\x{69B9}\x{69BA}\x{69BB}\x{69BC}\x{69BD}\x{69BE}\x{69BF}' - . '\x{69C1}\x{69C2}\x{69C3}\x{69C4}\x{69C5}\x{69C6}\x{69C7}\x{69C8}\x{69C9}' - . '\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}\x{69CF}\x{69D0}\x{69D3}\x{69D4}' - . '\x{69D8}\x{69D9}\x{69DA}\x{69DB}\x{69DC}\x{69DD}\x{69DE}\x{69DF}\x{69E0}' - . '\x{69E1}\x{69E2}\x{69E3}\x{69E4}\x{69E5}\x{69E6}\x{69E7}\x{69E8}\x{69E9}' - . '\x{69EA}\x{69EB}\x{69EC}\x{69ED}\x{69EE}\x{69EF}\x{69F0}\x{69F1}\x{69F2}' - . '\x{69F3}\x{69F4}\x{69F5}\x{69F6}\x{69F7}\x{69F8}\x{69FA}\x{69FB}\x{69FC}' - . '\x{69FD}\x{69FE}\x{69FF}\x{6A00}\x{6A01}\x{6A02}\x{6A04}\x{6A05}\x{6A06}' - . '\x{6A07}\x{6A08}\x{6A09}\x{6A0A}\x{6A0B}\x{6A0D}\x{6A0E}\x{6A0F}\x{6A10}' - . '\x{6A11}\x{6A12}\x{6A13}\x{6A14}\x{6A15}\x{6A16}\x{6A17}\x{6A18}\x{6A19}' - . '\x{6A1A}\x{6A1B}\x{6A1D}\x{6A1E}\x{6A1F}\x{6A20}\x{6A21}\x{6A22}\x{6A23}' - . '\x{6A25}\x{6A26}\x{6A27}\x{6A28}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2C}\x{6A2D}' - . '\x{6A2E}\x{6A2F}\x{6A30}\x{6A31}\x{6A32}\x{6A33}\x{6A34}\x{6A35}\x{6A36}' - . '\x{6A38}\x{6A39}\x{6A3A}\x{6A3B}\x{6A3C}\x{6A3D}\x{6A3E}\x{6A3F}\x{6A40}' - . '\x{6A41}\x{6A42}\x{6A43}\x{6A44}\x{6A45}\x{6A46}\x{6A47}\x{6A48}\x{6A49}' - . '\x{6A4B}\x{6A4C}\x{6A4D}\x{6A4E}\x{6A4F}\x{6A50}\x{6A51}\x{6A52}\x{6A54}' - . '\x{6A55}\x{6A56}\x{6A57}\x{6A58}\x{6A59}\x{6A5A}\x{6A5B}\x{6A5D}\x{6A5E}' - . '\x{6A5F}\x{6A60}\x{6A61}\x{6A62}\x{6A63}\x{6A64}\x{6A65}\x{6A66}\x{6A67}' - . '\x{6A68}\x{6A69}\x{6A6A}\x{6A6B}\x{6A6C}\x{6A6D}\x{6A6F}\x{6A71}\x{6A72}' - . '\x{6A73}\x{6A74}\x{6A75}\x{6A76}\x{6A77}\x{6A78}\x{6A79}\x{6A7A}\x{6A7B}' - . '\x{6A7C}\x{6A7D}\x{6A7E}\x{6A7F}\x{6A80}\x{6A81}\x{6A82}\x{6A83}\x{6A84}' - . '\x{6A85}\x{6A87}\x{6A88}\x{6A89}\x{6A8B}\x{6A8C}\x{6A8D}\x{6A8E}\x{6A90}' - . '\x{6A91}\x{6A92}\x{6A93}\x{6A94}\x{6A95}\x{6A96}\x{6A97}\x{6A98}\x{6A9A}' - . '\x{6A9B}\x{6A9C}\x{6A9E}\x{6A9F}\x{6AA0}\x{6AA1}\x{6AA2}\x{6AA3}\x{6AA4}' - . '\x{6AA5}\x{6AA6}\x{6AA7}\x{6AA8}\x{6AA9}\x{6AAB}\x{6AAC}\x{6AAD}\x{6AAE}' - . '\x{6AAF}\x{6AB0}\x{6AB2}\x{6AB3}\x{6AB4}\x{6AB5}\x{6AB6}\x{6AB7}\x{6AB8}' - . '\x{6AB9}\x{6ABA}\x{6ABB}\x{6ABC}\x{6ABD}\x{6ABF}\x{6AC1}\x{6AC2}\x{6AC3}' - . '\x{6AC5}\x{6AC6}\x{6AC7}\x{6ACA}\x{6ACB}\x{6ACC}\x{6ACD}\x{6ACE}\x{6ACF}' - . '\x{6AD0}\x{6AD1}\x{6AD2}\x{6AD3}\x{6AD4}\x{6AD5}\x{6AD6}\x{6AD7}\x{6AD9}' - . '\x{6ADA}\x{6ADB}\x{6ADC}\x{6ADD}\x{6ADE}\x{6ADF}\x{6AE0}\x{6AE1}\x{6AE2}' - . '\x{6AE3}\x{6AE4}\x{6AE5}\x{6AE6}\x{6AE7}\x{6AE8}\x{6AEA}\x{6AEB}\x{6AEC}' - . '\x{6AED}\x{6AEE}\x{6AEF}\x{6AF0}\x{6AF1}\x{6AF2}\x{6AF3}\x{6AF4}\x{6AF5}' - . '\x{6AF6}\x{6AF7}\x{6AF8}\x{6AF9}\x{6AFA}\x{6AFB}\x{6AFC}\x{6AFD}\x{6AFE}' - . '\x{6AFF}\x{6B00}\x{6B01}\x{6B02}\x{6B03}\x{6B04}\x{6B05}\x{6B06}\x{6B07}' - . '\x{6B08}\x{6B09}\x{6B0A}\x{6B0B}\x{6B0C}\x{6B0D}\x{6B0F}\x{6B10}\x{6B11}' - . '\x{6B12}\x{6B13}\x{6B14}\x{6B15}\x{6B16}\x{6B17}\x{6B18}\x{6B19}\x{6B1A}' - . '\x{6B1C}\x{6B1D}\x{6B1E}\x{6B1F}\x{6B20}\x{6B21}\x{6B22}\x{6B23}\x{6B24}' - . '\x{6B25}\x{6B26}\x{6B27}\x{6B28}\x{6B29}\x{6B2A}\x{6B2B}\x{6B2C}\x{6B2D}' - . '\x{6B2F}\x{6B30}\x{6B31}\x{6B32}\x{6B33}\x{6B34}\x{6B36}\x{6B37}\x{6B38}' - . '\x{6B39}\x{6B3A}\x{6B3B}\x{6B3C}\x{6B3D}\x{6B3E}\x{6B3F}\x{6B41}\x{6B42}' - . '\x{6B43}\x{6B44}\x{6B45}\x{6B46}\x{6B47}\x{6B48}\x{6B49}\x{6B4A}\x{6B4B}' - . '\x{6B4C}\x{6B4D}\x{6B4E}\x{6B4F}\x{6B50}\x{6B51}\x{6B52}\x{6B53}\x{6B54}' - . '\x{6B55}\x{6B56}\x{6B59}\x{6B5A}\x{6B5B}\x{6B5C}\x{6B5E}\x{6B5F}\x{6B60}' - . '\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B65}\x{6B66}\x{6B67}\x{6B69}\x{6B6A}' - . '\x{6B6B}\x{6B6D}\x{6B6F}\x{6B70}\x{6B72}\x{6B73}\x{6B74}\x{6B76}\x{6B77}' - . '\x{6B78}\x{6B79}\x{6B7A}\x{6B7B}\x{6B7C}\x{6B7E}\x{6B7F}\x{6B80}\x{6B81}' - . '\x{6B82}\x{6B83}\x{6B84}\x{6B85}\x{6B86}\x{6B87}\x{6B88}\x{6B89}\x{6B8A}' - . '\x{6B8B}\x{6B8C}\x{6B8D}\x{6B8E}\x{6B8F}\x{6B90}\x{6B91}\x{6B92}\x{6B93}' - . '\x{6B94}\x{6B95}\x{6B96}\x{6B97}\x{6B98}\x{6B99}\x{6B9A}\x{6B9B}\x{6B9C}' - . '\x{6B9D}\x{6B9E}\x{6B9F}\x{6BA0}\x{6BA1}\x{6BA2}\x{6BA3}\x{6BA4}\x{6BA5}' - . '\x{6BA6}\x{6BA7}\x{6BA8}\x{6BA9}\x{6BAA}\x{6BAB}\x{6BAC}\x{6BAD}\x{6BAE}' - . '\x{6BAF}\x{6BB0}\x{6BB2}\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB6}\x{6BB7}\x{6BB9}' - . '\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBD}\x{6BBE}\x{6BBF}\x{6BC0}\x{6BC1}\x{6BC2}' - . '\x{6BC3}\x{6BC4}\x{6BC5}\x{6BC6}\x{6BC7}\x{6BC8}\x{6BC9}\x{6BCA}\x{6BCB}' - . '\x{6BCC}\x{6BCD}\x{6BCE}\x{6BCF}\x{6BD0}\x{6BD1}\x{6BD2}\x{6BD3}\x{6BD4}' - . '\x{6BD5}\x{6BD6}\x{6BD7}\x{6BD8}\x{6BD9}\x{6BDA}\x{6BDB}\x{6BDC}\x{6BDD}' - . '\x{6BDE}\x{6BDF}\x{6BE0}\x{6BE1}\x{6BE2}\x{6BE3}\x{6BE4}\x{6BE5}\x{6BE6}' - . '\x{6BE7}\x{6BE8}\x{6BEA}\x{6BEB}\x{6BEC}\x{6BED}\x{6BEE}\x{6BEF}\x{6BF0}' - . '\x{6BF2}\x{6BF3}\x{6BF5}\x{6BF6}\x{6BF7}\x{6BF8}\x{6BF9}\x{6BFB}\x{6BFC}' - . '\x{6BFD}\x{6BFE}\x{6BFF}\x{6C00}\x{6C01}\x{6C02}\x{6C03}\x{6C04}\x{6C05}' - . '\x{6C06}\x{6C07}\x{6C08}\x{6C09}\x{6C0B}\x{6C0C}\x{6C0D}\x{6C0E}\x{6C0F}' - . '\x{6C10}\x{6C11}\x{6C12}\x{6C13}\x{6C14}\x{6C15}\x{6C16}\x{6C18}\x{6C19}' - . '\x{6C1A}\x{6C1B}\x{6C1D}\x{6C1E}\x{6C1F}\x{6C20}\x{6C21}\x{6C22}\x{6C23}' - . '\x{6C24}\x{6C25}\x{6C26}\x{6C27}\x{6C28}\x{6C29}\x{6C2A}\x{6C2B}\x{6C2C}' - . '\x{6C2E}\x{6C2F}\x{6C30}\x{6C31}\x{6C32}\x{6C33}\x{6C34}\x{6C35}\x{6C36}' - . '\x{6C37}\x{6C38}\x{6C3A}\x{6C3B}\x{6C3D}\x{6C3E}\x{6C3F}\x{6C40}\x{6C41}' - . '\x{6C42}\x{6C43}\x{6C44}\x{6C46}\x{6C47}\x{6C48}\x{6C49}\x{6C4A}\x{6C4B}' - . '\x{6C4C}\x{6C4D}\x{6C4E}\x{6C4F}\x{6C50}\x{6C51}\x{6C52}\x{6C53}\x{6C54}' - . '\x{6C55}\x{6C56}\x{6C57}\x{6C58}\x{6C59}\x{6C5A}\x{6C5B}\x{6C5C}\x{6C5D}' - . '\x{6C5E}\x{6C5F}\x{6C60}\x{6C61}\x{6C62}\x{6C63}\x{6C64}\x{6C65}\x{6C66}' - . '\x{6C67}\x{6C68}\x{6C69}\x{6C6A}\x{6C6B}\x{6C6D}\x{6C6F}\x{6C70}\x{6C71}' - . '\x{6C72}\x{6C73}\x{6C74}\x{6C75}\x{6C76}\x{6C77}\x{6C78}\x{6C79}\x{6C7A}' - . '\x{6C7B}\x{6C7C}\x{6C7D}\x{6C7E}\x{6C7F}\x{6C80}\x{6C81}\x{6C82}\x{6C83}' - . '\x{6C84}\x{6C85}\x{6C86}\x{6C87}\x{6C88}\x{6C89}\x{6C8A}\x{6C8B}\x{6C8C}' - . '\x{6C8D}\x{6C8E}\x{6C8F}\x{6C90}\x{6C91}\x{6C92}\x{6C93}\x{6C94}\x{6C95}' - . '\x{6C96}\x{6C97}\x{6C98}\x{6C99}\x{6C9A}\x{6C9B}\x{6C9C}\x{6C9D}\x{6C9E}' - . '\x{6C9F}\x{6CA1}\x{6CA2}\x{6CA3}\x{6CA4}\x{6CA5}\x{6CA6}\x{6CA7}\x{6CA8}' - . '\x{6CA9}\x{6CAA}\x{6CAB}\x{6CAC}\x{6CAD}\x{6CAE}\x{6CAF}\x{6CB0}\x{6CB1}' - . '\x{6CB2}\x{6CB3}\x{6CB4}\x{6CB5}\x{6CB6}\x{6CB7}\x{6CB8}\x{6CB9}\x{6CBA}' - . '\x{6CBB}\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC0}\x{6CC1}\x{6CC2}\x{6CC3}' - . '\x{6CC4}\x{6CC5}\x{6CC6}\x{6CC7}\x{6CC8}\x{6CC9}\x{6CCA}\x{6CCB}\x{6CCC}' - . '\x{6CCD}\x{6CCE}\x{6CCF}\x{6CD0}\x{6CD1}\x{6CD2}\x{6CD3}\x{6CD4}\x{6CD5}' - . '\x{6CD6}\x{6CD7}\x{6CD9}\x{6CDA}\x{6CDB}\x{6CDC}\x{6CDD}\x{6CDE}\x{6CDF}' - . '\x{6CE0}\x{6CE1}\x{6CE2}\x{6CE3}\x{6CE4}\x{6CE5}\x{6CE6}\x{6CE7}\x{6CE8}' - . '\x{6CE9}\x{6CEA}\x{6CEB}\x{6CEC}\x{6CED}\x{6CEE}\x{6CEF}\x{6CF0}\x{6CF1}' - . '\x{6CF2}\x{6CF3}\x{6CF5}\x{6CF6}\x{6CF7}\x{6CF8}\x{6CF9}\x{6CFA}\x{6CFB}' - . '\x{6CFC}\x{6CFD}\x{6CFE}\x{6CFF}\x{6D00}\x{6D01}\x{6D03}\x{6D04}\x{6D05}' - . '\x{6D06}\x{6D07}\x{6D08}\x{6D09}\x{6D0A}\x{6D0B}\x{6D0C}\x{6D0D}\x{6D0E}' - . '\x{6D0F}\x{6D10}\x{6D11}\x{6D12}\x{6D13}\x{6D14}\x{6D15}\x{6D16}\x{6D17}' - . '\x{6D18}\x{6D19}\x{6D1A}\x{6D1B}\x{6D1D}\x{6D1E}\x{6D1F}\x{6D20}\x{6D21}' - . '\x{6D22}\x{6D23}\x{6D25}\x{6D26}\x{6D27}\x{6D28}\x{6D29}\x{6D2A}\x{6D2B}' - . '\x{6D2C}\x{6D2D}\x{6D2E}\x{6D2F}\x{6D30}\x{6D31}\x{6D32}\x{6D33}\x{6D34}' - . '\x{6D35}\x{6D36}\x{6D37}\x{6D38}\x{6D39}\x{6D3A}\x{6D3B}\x{6D3C}\x{6D3D}' - . '\x{6D3E}\x{6D3F}\x{6D40}\x{6D41}\x{6D42}\x{6D43}\x{6D44}\x{6D45}\x{6D46}' - . '\x{6D47}\x{6D48}\x{6D49}\x{6D4A}\x{6D4B}\x{6D4C}\x{6D4D}\x{6D4E}\x{6D4F}' - . '\x{6D50}\x{6D51}\x{6D52}\x{6D53}\x{6D54}\x{6D55}\x{6D56}\x{6D57}\x{6D58}' - . '\x{6D59}\x{6D5A}\x{6D5B}\x{6D5C}\x{6D5D}\x{6D5E}\x{6D5F}\x{6D60}\x{6D61}' - . '\x{6D62}\x{6D63}\x{6D64}\x{6D65}\x{6D66}\x{6D67}\x{6D68}\x{6D69}\x{6D6A}' - . '\x{6D6B}\x{6D6C}\x{6D6D}\x{6D6E}\x{6D6F}\x{6D70}\x{6D72}\x{6D73}\x{6D74}' - . '\x{6D75}\x{6D76}\x{6D77}\x{6D78}\x{6D79}\x{6D7A}\x{6D7B}\x{6D7C}\x{6D7D}' - . '\x{6D7E}\x{6D7F}\x{6D80}\x{6D82}\x{6D83}\x{6D84}\x{6D85}\x{6D86}\x{6D87}' - . '\x{6D88}\x{6D89}\x{6D8A}\x{6D8B}\x{6D8C}\x{6D8D}\x{6D8E}\x{6D8F}\x{6D90}' - . '\x{6D91}\x{6D92}\x{6D93}\x{6D94}\x{6D95}\x{6D97}\x{6D98}\x{6D99}\x{6D9A}' - . '\x{6D9B}\x{6D9D}\x{6D9E}\x{6D9F}\x{6DA0}\x{6DA1}\x{6DA2}\x{6DA3}\x{6DA4}' - . '\x{6DA5}\x{6DA6}\x{6DA7}\x{6DA8}\x{6DA9}\x{6DAA}\x{6DAB}\x{6DAC}\x{6DAD}' - . '\x{6DAE}\x{6DAF}\x{6DB2}\x{6DB3}\x{6DB4}\x{6DB5}\x{6DB7}\x{6DB8}\x{6DB9}' - . '\x{6DBA}\x{6DBB}\x{6DBC}\x{6DBD}\x{6DBE}\x{6DBF}\x{6DC0}\x{6DC1}\x{6DC2}' - . '\x{6DC3}\x{6DC4}\x{6DC5}\x{6DC6}\x{6DC7}\x{6DC8}\x{6DC9}\x{6DCA}\x{6DCB}' - . '\x{6DCC}\x{6DCD}\x{6DCE}\x{6DCF}\x{6DD0}\x{6DD1}\x{6DD2}\x{6DD3}\x{6DD4}' - . '\x{6DD5}\x{6DD6}\x{6DD7}\x{6DD8}\x{6DD9}\x{6DDA}\x{6DDB}\x{6DDC}\x{6DDD}' - . '\x{6DDE}\x{6DDF}\x{6DE0}\x{6DE1}\x{6DE2}\x{6DE3}\x{6DE4}\x{6DE5}\x{6DE6}' - . '\x{6DE7}\x{6DE8}\x{6DE9}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DED}\x{6DEE}\x{6DEF}' - . '\x{6DF0}\x{6DF1}\x{6DF2}\x{6DF3}\x{6DF4}\x{6DF5}\x{6DF6}\x{6DF7}\x{6DF8}' - . '\x{6DF9}\x{6DFA}\x{6DFB}\x{6DFC}\x{6DFD}\x{6E00}\x{6E03}\x{6E04}\x{6E05}' - . '\x{6E07}\x{6E08}\x{6E09}\x{6E0A}\x{6E0B}\x{6E0C}\x{6E0D}\x{6E0E}\x{6E0F}' - . '\x{6E10}\x{6E11}\x{6E14}\x{6E15}\x{6E16}\x{6E17}\x{6E19}\x{6E1A}\x{6E1B}' - . '\x{6E1C}\x{6E1D}\x{6E1E}\x{6E1F}\x{6E20}\x{6E21}\x{6E22}\x{6E23}\x{6E24}' - . '\x{6E25}\x{6E26}\x{6E27}\x{6E28}\x{6E29}\x{6E2B}\x{6E2C}\x{6E2D}\x{6E2E}' - . '\x{6E2F}\x{6E30}\x{6E31}\x{6E32}\x{6E33}\x{6E34}\x{6E35}\x{6E36}\x{6E37}' - . '\x{6E38}\x{6E39}\x{6E3A}\x{6E3B}\x{6E3C}\x{6E3D}\x{6E3E}\x{6E3F}\x{6E40}' - . '\x{6E41}\x{6E42}\x{6E43}\x{6E44}\x{6E45}\x{6E46}\x{6E47}\x{6E48}\x{6E49}' - . '\x{6E4A}\x{6E4B}\x{6E4D}\x{6E4E}\x{6E4F}\x{6E50}\x{6E51}\x{6E52}\x{6E53}' - . '\x{6E54}\x{6E55}\x{6E56}\x{6E57}\x{6E58}\x{6E59}\x{6E5A}\x{6E5B}\x{6E5C}' - . '\x{6E5D}\x{6E5E}\x{6E5F}\x{6E60}\x{6E61}\x{6E62}\x{6E63}\x{6E64}\x{6E65}' - . '\x{6E66}\x{6E67}\x{6E68}\x{6E69}\x{6E6A}\x{6E6B}\x{6E6D}\x{6E6E}\x{6E6F}' - . '\x{6E70}\x{6E71}\x{6E72}\x{6E73}\x{6E74}\x{6E75}\x{6E77}\x{6E78}\x{6E79}' - . '\x{6E7E}\x{6E7F}\x{6E80}\x{6E81}\x{6E82}\x{6E83}\x{6E84}\x{6E85}\x{6E86}' - . '\x{6E87}\x{6E88}\x{6E89}\x{6E8A}\x{6E8D}\x{6E8E}\x{6E8F}\x{6E90}\x{6E91}' - . '\x{6E92}\x{6E93}\x{6E94}\x{6E96}\x{6E97}\x{6E98}\x{6E99}\x{6E9A}\x{6E9B}' - . '\x{6E9C}\x{6E9D}\x{6E9E}\x{6E9F}\x{6EA0}\x{6EA1}\x{6EA2}\x{6EA3}\x{6EA4}' - . '\x{6EA5}\x{6EA6}\x{6EA7}\x{6EA8}\x{6EA9}\x{6EAA}\x{6EAB}\x{6EAC}\x{6EAD}' - . '\x{6EAE}\x{6EAF}\x{6EB0}\x{6EB1}\x{6EB2}\x{6EB3}\x{6EB4}\x{6EB5}\x{6EB6}' - . '\x{6EB7}\x{6EB8}\x{6EB9}\x{6EBA}\x{6EBB}\x{6EBC}\x{6EBD}\x{6EBE}\x{6EBF}' - . '\x{6EC0}\x{6EC1}\x{6EC2}\x{6EC3}\x{6EC4}\x{6EC5}\x{6EC6}\x{6EC7}\x{6EC8}' - . '\x{6EC9}\x{6ECA}\x{6ECB}\x{6ECC}\x{6ECD}\x{6ECE}\x{6ECF}\x{6ED0}\x{6ED1}' - . '\x{6ED2}\x{6ED3}\x{6ED4}\x{6ED5}\x{6ED6}\x{6ED7}\x{6ED8}\x{6ED9}\x{6EDA}' - . '\x{6EDC}\x{6EDE}\x{6EDF}\x{6EE0}\x{6EE1}\x{6EE2}\x{6EE4}\x{6EE5}\x{6EE6}' - . '\x{6EE7}\x{6EE8}\x{6EE9}\x{6EEA}\x{6EEB}\x{6EEC}\x{6EED}\x{6EEE}\x{6EEF}' - . '\x{6EF0}\x{6EF1}\x{6EF2}\x{6EF3}\x{6EF4}\x{6EF5}\x{6EF6}\x{6EF7}\x{6EF8}' - . '\x{6EF9}\x{6EFA}\x{6EFB}\x{6EFC}\x{6EFD}\x{6EFE}\x{6EFF}\x{6F00}\x{6F01}' - . '\x{6F02}\x{6F03}\x{6F05}\x{6F06}\x{6F07}\x{6F08}\x{6F09}\x{6F0A}\x{6F0C}' - . '\x{6F0D}\x{6F0E}\x{6F0F}\x{6F10}\x{6F11}\x{6F12}\x{6F13}\x{6F14}\x{6F15}' - . '\x{6F16}\x{6F17}\x{6F18}\x{6F19}\x{6F1A}\x{6F1B}\x{6F1C}\x{6F1D}\x{6F1E}' - . '\x{6F1F}\x{6F20}\x{6F21}\x{6F22}\x{6F23}\x{6F24}\x{6F25}\x{6F26}\x{6F27}' - . '\x{6F28}\x{6F29}\x{6F2A}\x{6F2B}\x{6F2C}\x{6F2D}\x{6F2E}\x{6F2F}\x{6F30}' - . '\x{6F31}\x{6F32}\x{6F33}\x{6F34}\x{6F35}\x{6F36}\x{6F37}\x{6F38}\x{6F39}' - . '\x{6F3A}\x{6F3B}\x{6F3C}\x{6F3D}\x{6F3E}\x{6F3F}\x{6F40}\x{6F41}\x{6F43}' - . '\x{6F44}\x{6F45}\x{6F46}\x{6F47}\x{6F49}\x{6F4B}\x{6F4C}\x{6F4D}\x{6F4E}' - . '\x{6F4F}\x{6F50}\x{6F51}\x{6F52}\x{6F53}\x{6F54}\x{6F55}\x{6F56}\x{6F57}' - . '\x{6F58}\x{6F59}\x{6F5A}\x{6F5B}\x{6F5C}\x{6F5D}\x{6F5E}\x{6F5F}\x{6F60}' - . '\x{6F61}\x{6F62}\x{6F63}\x{6F64}\x{6F65}\x{6F66}\x{6F67}\x{6F68}\x{6F69}' - . '\x{6F6A}\x{6F6B}\x{6F6C}\x{6F6D}\x{6F6E}\x{6F6F}\x{6F70}\x{6F71}\x{6F72}' - . '\x{6F73}\x{6F74}\x{6F75}\x{6F76}\x{6F77}\x{6F78}\x{6F7A}\x{6F7B}\x{6F7C}' - . '\x{6F7D}\x{6F7E}\x{6F7F}\x{6F80}\x{6F81}\x{6F82}\x{6F83}\x{6F84}\x{6F85}' - . '\x{6F86}\x{6F87}\x{6F88}\x{6F89}\x{6F8A}\x{6F8B}\x{6F8C}\x{6F8D}\x{6F8E}' - . '\x{6F8F}\x{6F90}\x{6F91}\x{6F92}\x{6F93}\x{6F94}\x{6F95}\x{6F96}\x{6F97}' - . '\x{6F99}\x{6F9B}\x{6F9C}\x{6F9D}\x{6F9E}\x{6FA0}\x{6FA1}\x{6FA2}\x{6FA3}' - . '\x{6FA4}\x{6FA5}\x{6FA6}\x{6FA7}\x{6FA8}\x{6FA9}\x{6FAA}\x{6FAB}\x{6FAC}' - . '\x{6FAD}\x{6FAE}\x{6FAF}\x{6FB0}\x{6FB1}\x{6FB2}\x{6FB3}\x{6FB4}\x{6FB5}' - . '\x{6FB6}\x{6FB8}\x{6FB9}\x{6FBA}\x{6FBB}\x{6FBC}\x{6FBD}\x{6FBE}\x{6FBF}' - . '\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC4}\x{6FC6}\x{6FC7}\x{6FC8}\x{6FC9}' - . '\x{6FCA}\x{6FCB}\x{6FCC}\x{6FCD}\x{6FCE}\x{6FCF}\x{6FD1}\x{6FD2}\x{6FD4}' - . '\x{6FD5}\x{6FD6}\x{6FD7}\x{6FD8}\x{6FD9}\x{6FDA}\x{6FDB}\x{6FDC}\x{6FDD}' - . '\x{6FDE}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE2}\x{6FE3}\x{6FE4}\x{6FE5}\x{6FE6}' - . '\x{6FE7}\x{6FE8}\x{6FE9}\x{6FEA}\x{6FEB}\x{6FEC}\x{6FED}\x{6FEE}\x{6FEF}' - . '\x{6FF0}\x{6FF1}\x{6FF2}\x{6FF3}\x{6FF4}\x{6FF6}\x{6FF7}\x{6FF8}\x{6FF9}' - . '\x{6FFA}\x{6FFB}\x{6FFC}\x{6FFE}\x{6FFF}\x{7000}\x{7001}\x{7002}\x{7003}' - . '\x{7004}\x{7005}\x{7006}\x{7007}\x{7008}\x{7009}\x{700A}\x{700B}\x{700C}' - . '\x{700D}\x{700E}\x{700F}\x{7011}\x{7012}\x{7014}\x{7015}\x{7016}\x{7017}' - . '\x{7018}\x{7019}\x{701A}\x{701B}\x{701C}\x{701D}\x{701F}\x{7020}\x{7021}' - . '\x{7022}\x{7023}\x{7024}\x{7025}\x{7026}\x{7027}\x{7028}\x{7029}\x{702A}' - . '\x{702B}\x{702C}\x{702D}\x{702E}\x{702F}\x{7030}\x{7031}\x{7032}\x{7033}' - . '\x{7034}\x{7035}\x{7036}\x{7037}\x{7038}\x{7039}\x{703A}\x{703B}\x{703C}' - . '\x{703D}\x{703E}\x{703F}\x{7040}\x{7041}\x{7042}\x{7043}\x{7044}\x{7045}' - . '\x{7046}\x{7048}\x{7049}\x{704A}\x{704C}\x{704D}\x{704F}\x{7050}\x{7051}' - . '\x{7052}\x{7053}\x{7054}\x{7055}\x{7056}\x{7057}\x{7058}\x{7059}\x{705A}' - . '\x{705B}\x{705C}\x{705D}\x{705E}\x{705F}\x{7060}\x{7061}\x{7062}\x{7063}' - . '\x{7064}\x{7065}\x{7066}\x{7067}\x{7068}\x{7069}\x{706A}\x{706B}\x{706C}' - . '\x{706D}\x{706E}\x{706F}\x{7070}\x{7071}\x{7074}\x{7075}\x{7076}\x{7077}' - . '\x{7078}\x{7079}\x{707A}\x{707C}\x{707D}\x{707E}\x{707F}\x{7080}\x{7082}' - . '\x{7083}\x{7084}\x{7085}\x{7086}\x{7087}\x{7088}\x{7089}\x{708A}\x{708B}' - . '\x{708C}\x{708E}\x{708F}\x{7090}\x{7091}\x{7092}\x{7093}\x{7094}\x{7095}' - . '\x{7096}\x{7098}\x{7099}\x{709A}\x{709C}\x{709D}\x{709E}\x{709F}\x{70A0}' - . '\x{70A1}\x{70A2}\x{70A3}\x{70A4}\x{70A5}\x{70A6}\x{70A7}\x{70A8}\x{70A9}' - . '\x{70AB}\x{70AC}\x{70AD}\x{70AE}\x{70AF}\x{70B0}\x{70B1}\x{70B3}\x{70B4}' - . '\x{70B5}\x{70B7}\x{70B8}\x{70B9}\x{70BA}\x{70BB}\x{70BC}\x{70BD}\x{70BE}' - . '\x{70BF}\x{70C0}\x{70C1}\x{70C2}\x{70C3}\x{70C4}\x{70C5}\x{70C6}\x{70C7}' - . '\x{70C8}\x{70C9}\x{70CA}\x{70CB}\x{70CC}\x{70CD}\x{70CE}\x{70CF}\x{70D0}' - . '\x{70D1}\x{70D2}\x{70D3}\x{70D4}\x{70D6}\x{70D7}\x{70D8}\x{70D9}\x{70DA}' - . '\x{70DB}\x{70DC}\x{70DD}\x{70DE}\x{70DF}\x{70E0}\x{70E1}\x{70E2}\x{70E3}' - . '\x{70E4}\x{70E5}\x{70E6}\x{70E7}\x{70E8}\x{70E9}\x{70EA}\x{70EB}\x{70EC}' - . '\x{70ED}\x{70EE}\x{70EF}\x{70F0}\x{70F1}\x{70F2}\x{70F3}\x{70F4}\x{70F5}' - . '\x{70F6}\x{70F7}\x{70F8}\x{70F9}\x{70FA}\x{70FB}\x{70FC}\x{70FD}\x{70FF}' - . '\x{7100}\x{7101}\x{7102}\x{7103}\x{7104}\x{7105}\x{7106}\x{7107}\x{7109}' - . '\x{710A}\x{710B}\x{710C}\x{710D}\x{710E}\x{710F}\x{7110}\x{7111}\x{7112}' - . '\x{7113}\x{7115}\x{7116}\x{7117}\x{7118}\x{7119}\x{711A}\x{711B}\x{711C}' - . '\x{711D}\x{711E}\x{711F}\x{7120}\x{7121}\x{7122}\x{7123}\x{7125}\x{7126}' - . '\x{7127}\x{7128}\x{7129}\x{712A}\x{712B}\x{712C}\x{712D}\x{712E}\x{712F}' - . '\x{7130}\x{7131}\x{7132}\x{7135}\x{7136}\x{7137}\x{7138}\x{7139}\x{713A}' - . '\x{713B}\x{713D}\x{713E}\x{713F}\x{7140}\x{7141}\x{7142}\x{7143}\x{7144}' - . '\x{7145}\x{7146}\x{7147}\x{7148}\x{7149}\x{714A}\x{714B}\x{714C}\x{714D}' - . '\x{714E}\x{714F}\x{7150}\x{7151}\x{7152}\x{7153}\x{7154}\x{7156}\x{7158}' - . '\x{7159}\x{715A}\x{715B}\x{715C}\x{715D}\x{715E}\x{715F}\x{7160}\x{7161}' - . '\x{7162}\x{7163}\x{7164}\x{7165}\x{7166}\x{7167}\x{7168}\x{7169}\x{716A}' - . '\x{716C}\x{716E}\x{716F}\x{7170}\x{7171}\x{7172}\x{7173}\x{7174}\x{7175}' - . '\x{7176}\x{7177}\x{7178}\x{7179}\x{717A}\x{717B}\x{717C}\x{717D}\x{717E}' - . '\x{717F}\x{7180}\x{7181}\x{7182}\x{7183}\x{7184}\x{7185}\x{7186}\x{7187}' - . '\x{7188}\x{7189}\x{718A}\x{718B}\x{718C}\x{718E}\x{718F}\x{7190}\x{7191}' - . '\x{7192}\x{7193}\x{7194}\x{7195}\x{7197}\x{7198}\x{7199}\x{719A}\x{719B}' - . '\x{719C}\x{719D}\x{719E}\x{719F}\x{71A0}\x{71A1}\x{71A2}\x{71A3}\x{71A4}' - . '\x{71A5}\x{71A7}\x{71A8}\x{71A9}\x{71AA}\x{71AC}\x{71AD}\x{71AE}\x{71AF}' - . '\x{71B0}\x{71B1}\x{71B2}\x{71B3}\x{71B4}\x{71B5}\x{71B7}\x{71B8}\x{71B9}' - . '\x{71BA}\x{71BB}\x{71BC}\x{71BD}\x{71BE}\x{71BF}\x{71C0}\x{71C1}\x{71C2}' - . '\x{71C3}\x{71C4}\x{71C5}\x{71C6}\x{71C7}\x{71C8}\x{71C9}\x{71CA}\x{71CB}' - . '\x{71CD}\x{71CE}\x{71CF}\x{71D0}\x{71D1}\x{71D2}\x{71D4}\x{71D5}\x{71D6}' - . '\x{71D7}\x{71D8}\x{71D9}\x{71DA}\x{71DB}\x{71DC}\x{71DD}\x{71DE}\x{71DF}' - . '\x{71E0}\x{71E1}\x{71E2}\x{71E3}\x{71E4}\x{71E5}\x{71E6}\x{71E7}\x{71E8}' - . '\x{71E9}\x{71EA}\x{71EB}\x{71EC}\x{71ED}\x{71EE}\x{71EF}\x{71F0}\x{71F1}' - . '\x{71F2}\x{71F4}\x{71F5}\x{71F6}\x{71F7}\x{71F8}\x{71F9}\x{71FB}\x{71FC}' - . '\x{71FD}\x{71FE}\x{71FF}\x{7201}\x{7202}\x{7203}\x{7204}\x{7205}\x{7206}' - . '\x{7207}\x{7208}\x{7209}\x{720A}\x{720C}\x{720D}\x{720E}\x{720F}\x{7210}' - . '\x{7212}\x{7213}\x{7214}\x{7216}\x{7218}\x{7219}\x{721A}\x{721B}\x{721C}' - . '\x{721D}\x{721E}\x{721F}\x{7221}\x{7222}\x{7223}\x{7226}\x{7227}\x{7228}' - . '\x{7229}\x{722A}\x{722B}\x{722C}\x{722D}\x{722E}\x{7230}\x{7231}\x{7232}' - . '\x{7233}\x{7235}\x{7236}\x{7237}\x{7238}\x{7239}\x{723A}\x{723B}\x{723C}' - . '\x{723D}\x{723E}\x{723F}\x{7240}\x{7241}\x{7242}\x{7243}\x{7244}\x{7246}' - . '\x{7247}\x{7248}\x{7249}\x{724A}\x{724B}\x{724C}\x{724D}\x{724F}\x{7251}' - . '\x{7252}\x{7253}\x{7254}\x{7256}\x{7257}\x{7258}\x{7259}\x{725A}\x{725B}' - . '\x{725C}\x{725D}\x{725E}\x{725F}\x{7260}\x{7261}\x{7262}\x{7263}\x{7264}' - . '\x{7265}\x{7266}\x{7267}\x{7268}\x{7269}\x{726A}\x{726B}\x{726C}\x{726D}' - . '\x{726E}\x{726F}\x{7270}\x{7271}\x{7272}\x{7273}\x{7274}\x{7275}\x{7276}' - . '\x{7277}\x{7278}\x{7279}\x{727A}\x{727B}\x{727C}\x{727D}\x{727E}\x{727F}' - . '\x{7280}\x{7281}\x{7282}\x{7283}\x{7284}\x{7285}\x{7286}\x{7287}\x{7288}' - . '\x{7289}\x{728A}\x{728B}\x{728C}\x{728D}\x{728E}\x{728F}\x{7290}\x{7291}' - . '\x{7292}\x{7293}\x{7294}\x{7295}\x{7296}\x{7297}\x{7298}\x{7299}\x{729A}' - . '\x{729B}\x{729C}\x{729D}\x{729E}\x{729F}\x{72A1}\x{72A2}\x{72A3}\x{72A4}' - . '\x{72A5}\x{72A6}\x{72A7}\x{72A8}\x{72A9}\x{72AA}\x{72AC}\x{72AD}\x{72AE}' - . '\x{72AF}\x{72B0}\x{72B1}\x{72B2}\x{72B3}\x{72B4}\x{72B5}\x{72B6}\x{72B7}' - . '\x{72B8}\x{72B9}\x{72BA}\x{72BB}\x{72BC}\x{72BD}\x{72BF}\x{72C0}\x{72C1}' - . '\x{72C2}\x{72C3}\x{72C4}\x{72C5}\x{72C6}\x{72C7}\x{72C8}\x{72C9}\x{72CA}' - . '\x{72CB}\x{72CC}\x{72CD}\x{72CE}\x{72CF}\x{72D0}\x{72D1}\x{72D2}\x{72D3}' - . '\x{72D4}\x{72D5}\x{72D6}\x{72D7}\x{72D8}\x{72D9}\x{72DA}\x{72DB}\x{72DC}' - . '\x{72DD}\x{72DE}\x{72DF}\x{72E0}\x{72E1}\x{72E2}\x{72E3}\x{72E4}\x{72E5}' - . '\x{72E6}\x{72E7}\x{72E8}\x{72E9}\x{72EA}\x{72EB}\x{72EC}\x{72ED}\x{72EE}' - . '\x{72EF}\x{72F0}\x{72F1}\x{72F2}\x{72F3}\x{72F4}\x{72F5}\x{72F6}\x{72F7}' - . '\x{72F8}\x{72F9}\x{72FA}\x{72FB}\x{72FC}\x{72FD}\x{72FE}\x{72FF}\x{7300}' - . '\x{7301}\x{7303}\x{7304}\x{7305}\x{7306}\x{7307}\x{7308}\x{7309}\x{730A}' - . '\x{730B}\x{730C}\x{730D}\x{730E}\x{730F}\x{7311}\x{7312}\x{7313}\x{7314}' - . '\x{7315}\x{7316}\x{7317}\x{7318}\x{7319}\x{731A}\x{731B}\x{731C}\x{731D}' - . '\x{731E}\x{7320}\x{7321}\x{7322}\x{7323}\x{7324}\x{7325}\x{7326}\x{7327}' - . '\x{7329}\x{732A}\x{732B}\x{732C}\x{732D}\x{732E}\x{7330}\x{7331}\x{7332}' - . '\x{7333}\x{7334}\x{7335}\x{7336}\x{7337}\x{7338}\x{7339}\x{733A}\x{733B}' - . '\x{733C}\x{733D}\x{733E}\x{733F}\x{7340}\x{7341}\x{7342}\x{7343}\x{7344}' - . '\x{7345}\x{7346}\x{7347}\x{7348}\x{7349}\x{734A}\x{734B}\x{734C}\x{734D}' - . '\x{734E}\x{7350}\x{7351}\x{7352}\x{7354}\x{7355}\x{7356}\x{7357}\x{7358}' - . '\x{7359}\x{735A}\x{735B}\x{735C}\x{735D}\x{735E}\x{735F}\x{7360}\x{7361}' - . '\x{7362}\x{7364}\x{7365}\x{7366}\x{7367}\x{7368}\x{7369}\x{736A}\x{736B}' - . '\x{736C}\x{736D}\x{736E}\x{736F}\x{7370}\x{7371}\x{7372}\x{7373}\x{7374}' - . '\x{7375}\x{7376}\x{7377}\x{7378}\x{7379}\x{737A}\x{737B}\x{737C}\x{737D}' - . '\x{737E}\x{737F}\x{7380}\x{7381}\x{7382}\x{7383}\x{7384}\x{7385}\x{7386}' - . '\x{7387}\x{7388}\x{7389}\x{738A}\x{738B}\x{738C}\x{738D}\x{738E}\x{738F}' - . '\x{7390}\x{7391}\x{7392}\x{7393}\x{7394}\x{7395}\x{7396}\x{7397}\x{7398}' - . '\x{7399}\x{739A}\x{739B}\x{739D}\x{739E}\x{739F}\x{73A0}\x{73A1}\x{73A2}' - . '\x{73A3}\x{73A4}\x{73A5}\x{73A6}\x{73A7}\x{73A8}\x{73A9}\x{73AA}\x{73AB}' - . '\x{73AC}\x{73AD}\x{73AE}\x{73AF}\x{73B0}\x{73B1}\x{73B2}\x{73B3}\x{73B4}' - . '\x{73B5}\x{73B6}\x{73B7}\x{73B8}\x{73B9}\x{73BA}\x{73BB}\x{73BC}\x{73BD}' - . '\x{73BE}\x{73BF}\x{73C0}\x{73C2}\x{73C3}\x{73C4}\x{73C5}\x{73C6}\x{73C7}' - . '\x{73C8}\x{73C9}\x{73CA}\x{73CB}\x{73CC}\x{73CD}\x{73CE}\x{73CF}\x{73D0}' - . '\x{73D1}\x{73D2}\x{73D3}\x{73D4}\x{73D5}\x{73D6}\x{73D7}\x{73D8}\x{73D9}' - . '\x{73DA}\x{73DB}\x{73DC}\x{73DD}\x{73DE}\x{73DF}\x{73E0}\x{73E2}\x{73E3}' - . '\x{73E5}\x{73E6}\x{73E7}\x{73E8}\x{73E9}\x{73EA}\x{73EB}\x{73EC}\x{73ED}' - . '\x{73EE}\x{73EF}\x{73F0}\x{73F1}\x{73F2}\x{73F4}\x{73F5}\x{73F6}\x{73F7}' - . '\x{73F8}\x{73F9}\x{73FA}\x{73FC}\x{73FD}\x{73FE}\x{73FF}\x{7400}\x{7401}' - . '\x{7402}\x{7403}\x{7404}\x{7405}\x{7406}\x{7407}\x{7408}\x{7409}\x{740A}' - . '\x{740B}\x{740C}\x{740D}\x{740E}\x{740F}\x{7410}\x{7411}\x{7412}\x{7413}' - . '\x{7414}\x{7415}\x{7416}\x{7417}\x{7419}\x{741A}\x{741B}\x{741C}\x{741D}' - . '\x{741E}\x{741F}\x{7420}\x{7421}\x{7422}\x{7423}\x{7424}\x{7425}\x{7426}' - . '\x{7427}\x{7428}\x{7429}\x{742A}\x{742B}\x{742C}\x{742D}\x{742E}\x{742F}' - . '\x{7430}\x{7431}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{7437}\x{7438}' - . '\x{743A}\x{743B}\x{743C}\x{743D}\x{743F}\x{7440}\x{7441}\x{7442}\x{7443}' - . '\x{7444}\x{7445}\x{7446}\x{7448}\x{744A}\x{744B}\x{744C}\x{744D}\x{744E}' - . '\x{744F}\x{7450}\x{7451}\x{7452}\x{7453}\x{7454}\x{7455}\x{7456}\x{7457}' - . '\x{7459}\x{745A}\x{745B}\x{745C}\x{745D}\x{745E}\x{745F}\x{7461}\x{7462}' - . '\x{7463}\x{7464}\x{7465}\x{7466}\x{7467}\x{7468}\x{7469}\x{746A}\x{746B}' - . '\x{746C}\x{746D}\x{746E}\x{746F}\x{7470}\x{7471}\x{7472}\x{7473}\x{7474}' - . '\x{7475}\x{7476}\x{7477}\x{7478}\x{7479}\x{747A}\x{747C}\x{747D}\x{747E}' - . '\x{747F}\x{7480}\x{7481}\x{7482}\x{7483}\x{7485}\x{7486}\x{7487}\x{7488}' - . '\x{7489}\x{748A}\x{748B}\x{748C}\x{748D}\x{748E}\x{748F}\x{7490}\x{7491}' - . '\x{7492}\x{7493}\x{7494}\x{7495}\x{7497}\x{7498}\x{7499}\x{749A}\x{749B}' - . '\x{749C}\x{749E}\x{749F}\x{74A0}\x{74A1}\x{74A3}\x{74A4}\x{74A5}\x{74A6}' - . '\x{74A7}\x{74A8}\x{74A9}\x{74AA}\x{74AB}\x{74AC}\x{74AD}\x{74AE}\x{74AF}' - . '\x{74B0}\x{74B1}\x{74B2}\x{74B3}\x{74B4}\x{74B5}\x{74B6}\x{74B7}\x{74B8}' - . '\x{74B9}\x{74BA}\x{74BB}\x{74BC}\x{74BD}\x{74BE}\x{74BF}\x{74C0}\x{74C1}' - . '\x{74C2}\x{74C3}\x{74C4}\x{74C5}\x{74C6}\x{74CA}\x{74CB}\x{74CD}\x{74CE}' - . '\x{74CF}\x{74D0}\x{74D1}\x{74D2}\x{74D3}\x{74D4}\x{74D5}\x{74D6}\x{74D7}' - . '\x{74D8}\x{74D9}\x{74DA}\x{74DB}\x{74DC}\x{74DD}\x{74DE}\x{74DF}\x{74E0}' - . '\x{74E1}\x{74E2}\x{74E3}\x{74E4}\x{74E5}\x{74E6}\x{74E7}\x{74E8}\x{74E9}' - . '\x{74EA}\x{74EC}\x{74ED}\x{74EE}\x{74EF}\x{74F0}\x{74F1}\x{74F2}\x{74F3}' - . '\x{74F4}\x{74F5}\x{74F6}\x{74F7}\x{74F8}\x{74F9}\x{74FA}\x{74FB}\x{74FC}' - . '\x{74FD}\x{74FE}\x{74FF}\x{7500}\x{7501}\x{7502}\x{7503}\x{7504}\x{7505}' - . '\x{7506}\x{7507}\x{7508}\x{7509}\x{750A}\x{750B}\x{750C}\x{750D}\x{750F}' - . '\x{7510}\x{7511}\x{7512}\x{7513}\x{7514}\x{7515}\x{7516}\x{7517}\x{7518}' - . '\x{7519}\x{751A}\x{751B}\x{751C}\x{751D}\x{751E}\x{751F}\x{7521}\x{7522}' - . '\x{7523}\x{7524}\x{7525}\x{7526}\x{7527}\x{7528}\x{7529}\x{752A}\x{752B}' - . '\x{752C}\x{752D}\x{752E}\x{752F}\x{7530}\x{7531}\x{7532}\x{7533}\x{7535}' - . '\x{7536}\x{7537}\x{7538}\x{7539}\x{753A}\x{753B}\x{753C}\x{753D}\x{753E}' - . '\x{753F}\x{7540}\x{7542}\x{7543}\x{7544}\x{7545}\x{7546}\x{7547}\x{7548}' - . '\x{7549}\x{754B}\x{754C}\x{754D}\x{754E}\x{754F}\x{7550}\x{7551}\x{7553}' - . '\x{7554}\x{7556}\x{7557}\x{7558}\x{7559}\x{755A}\x{755B}\x{755C}\x{755D}' - . '\x{755F}\x{7560}\x{7562}\x{7563}\x{7564}\x{7565}\x{7566}\x{7567}\x{7568}' - . '\x{7569}\x{756A}\x{756B}\x{756C}\x{756D}\x{756E}\x{756F}\x{7570}\x{7572}' - . '\x{7574}\x{7575}\x{7576}\x{7577}\x{7578}\x{7579}\x{757C}\x{757D}\x{757E}' - . '\x{757F}\x{7580}\x{7581}\x{7582}\x{7583}\x{7584}\x{7586}\x{7587}\x{7588}' - . '\x{7589}\x{758A}\x{758B}\x{758C}\x{758D}\x{758F}\x{7590}\x{7591}\x{7592}' - . '\x{7593}\x{7594}\x{7595}\x{7596}\x{7597}\x{7598}\x{7599}\x{759A}\x{759B}' - . '\x{759C}\x{759D}\x{759E}\x{759F}\x{75A0}\x{75A1}\x{75A2}\x{75A3}\x{75A4}' - . '\x{75A5}\x{75A6}\x{75A7}\x{75A8}\x{75AA}\x{75AB}\x{75AC}\x{75AD}\x{75AE}' - . '\x{75AF}\x{75B0}\x{75B1}\x{75B2}\x{75B3}\x{75B4}\x{75B5}\x{75B6}\x{75B8}' - . '\x{75B9}\x{75BA}\x{75BB}\x{75BC}\x{75BD}\x{75BE}\x{75BF}\x{75C0}\x{75C1}' - . '\x{75C2}\x{75C3}\x{75C4}\x{75C5}\x{75C6}\x{75C7}\x{75C8}\x{75C9}\x{75CA}' - . '\x{75CB}\x{75CC}\x{75CD}\x{75CE}\x{75CF}\x{75D0}\x{75D1}\x{75D2}\x{75D3}' - . '\x{75D4}\x{75D5}\x{75D6}\x{75D7}\x{75D8}\x{75D9}\x{75DA}\x{75DB}\x{75DD}' - . '\x{75DE}\x{75DF}\x{75E0}\x{75E1}\x{75E2}\x{75E3}\x{75E4}\x{75E5}\x{75E6}' - . '\x{75E7}\x{75E8}\x{75EA}\x{75EB}\x{75EC}\x{75ED}\x{75EF}\x{75F0}\x{75F1}' - . '\x{75F2}\x{75F3}\x{75F4}\x{75F5}\x{75F6}\x{75F7}\x{75F8}\x{75F9}\x{75FA}' - . '\x{75FB}\x{75FC}\x{75FD}\x{75FE}\x{75FF}\x{7600}\x{7601}\x{7602}\x{7603}' - . '\x{7604}\x{7605}\x{7606}\x{7607}\x{7608}\x{7609}\x{760A}\x{760B}\x{760C}' - . '\x{760D}\x{760E}\x{760F}\x{7610}\x{7611}\x{7612}\x{7613}\x{7614}\x{7615}' - . '\x{7616}\x{7617}\x{7618}\x{7619}\x{761A}\x{761B}\x{761C}\x{761D}\x{761E}' - . '\x{761F}\x{7620}\x{7621}\x{7622}\x{7623}\x{7624}\x{7625}\x{7626}\x{7627}' - . '\x{7628}\x{7629}\x{762A}\x{762B}\x{762D}\x{762E}\x{762F}\x{7630}\x{7631}' - . '\x{7632}\x{7633}\x{7634}\x{7635}\x{7636}\x{7637}\x{7638}\x{7639}\x{763A}' - . '\x{763B}\x{763C}\x{763D}\x{763E}\x{763F}\x{7640}\x{7641}\x{7642}\x{7643}' - . '\x{7646}\x{7647}\x{7648}\x{7649}\x{764A}\x{764B}\x{764C}\x{764D}\x{764F}' - . '\x{7650}\x{7652}\x{7653}\x{7654}\x{7656}\x{7657}\x{7658}\x{7659}\x{765A}' - . '\x{765B}\x{765C}\x{765D}\x{765E}\x{765F}\x{7660}\x{7661}\x{7662}\x{7663}' - . '\x{7664}\x{7665}\x{7666}\x{7667}\x{7668}\x{7669}\x{766A}\x{766B}\x{766C}' - . '\x{766D}\x{766E}\x{766F}\x{7670}\x{7671}\x{7672}\x{7674}\x{7675}\x{7676}' - . '\x{7677}\x{7678}\x{7679}\x{767B}\x{767C}\x{767D}\x{767E}\x{767F}\x{7680}' - . '\x{7681}\x{7682}\x{7683}\x{7684}\x{7685}\x{7686}\x{7687}\x{7688}\x{7689}' - . '\x{768A}\x{768B}\x{768C}\x{768E}\x{768F}\x{7690}\x{7691}\x{7692}\x{7693}' - . '\x{7694}\x{7695}\x{7696}\x{7697}\x{7698}\x{7699}\x{769A}\x{769B}\x{769C}' - . '\x{769D}\x{769E}\x{769F}\x{76A0}\x{76A3}\x{76A4}\x{76A6}\x{76A7}\x{76A9}' - . '\x{76AA}\x{76AB}\x{76AC}\x{76AD}\x{76AE}\x{76AF}\x{76B0}\x{76B1}\x{76B2}' - . '\x{76B4}\x{76B5}\x{76B7}\x{76B8}\x{76BA}\x{76BB}\x{76BC}\x{76BD}\x{76BE}' - . '\x{76BF}\x{76C0}\x{76C2}\x{76C3}\x{76C4}\x{76C5}\x{76C6}\x{76C7}\x{76C8}' - . '\x{76C9}\x{76CA}\x{76CD}\x{76CE}\x{76CF}\x{76D0}\x{76D1}\x{76D2}\x{76D3}' - . '\x{76D4}\x{76D5}\x{76D6}\x{76D7}\x{76D8}\x{76DA}\x{76DB}\x{76DC}\x{76DD}' - . '\x{76DE}\x{76DF}\x{76E0}\x{76E1}\x{76E2}\x{76E3}\x{76E4}\x{76E5}\x{76E6}' - . '\x{76E7}\x{76E8}\x{76E9}\x{76EA}\x{76EC}\x{76ED}\x{76EE}\x{76EF}\x{76F0}' - . '\x{76F1}\x{76F2}\x{76F3}\x{76F4}\x{76F5}\x{76F6}\x{76F7}\x{76F8}\x{76F9}' - . '\x{76FA}\x{76FB}\x{76FC}\x{76FD}\x{76FE}\x{76FF}\x{7701}\x{7703}\x{7704}' - . '\x{7705}\x{7706}\x{7707}\x{7708}\x{7709}\x{770A}\x{770B}\x{770C}\x{770D}' - . '\x{770F}\x{7710}\x{7711}\x{7712}\x{7713}\x{7714}\x{7715}\x{7716}\x{7717}' - . '\x{7718}\x{7719}\x{771A}\x{771B}\x{771C}\x{771D}\x{771E}\x{771F}\x{7720}' - . '\x{7722}\x{7723}\x{7725}\x{7726}\x{7727}\x{7728}\x{7729}\x{772A}\x{772C}' - . '\x{772D}\x{772E}\x{772F}\x{7730}\x{7731}\x{7732}\x{7733}\x{7734}\x{7735}' - . '\x{7736}\x{7737}\x{7738}\x{7739}\x{773A}\x{773B}\x{773C}\x{773D}\x{773E}' - . '\x{7740}\x{7741}\x{7743}\x{7744}\x{7745}\x{7746}\x{7747}\x{7748}\x{7749}' - . '\x{774A}\x{774B}\x{774C}\x{774D}\x{774E}\x{774F}\x{7750}\x{7751}\x{7752}' - . '\x{7753}\x{7754}\x{7755}\x{7756}\x{7757}\x{7758}\x{7759}\x{775A}\x{775B}' - . '\x{775C}\x{775D}\x{775E}\x{775F}\x{7760}\x{7761}\x{7762}\x{7763}\x{7765}' - . '\x{7766}\x{7767}\x{7768}\x{7769}\x{776A}\x{776B}\x{776C}\x{776D}\x{776E}' - . '\x{776F}\x{7770}\x{7771}\x{7772}\x{7773}\x{7774}\x{7775}\x{7776}\x{7777}' - . '\x{7778}\x{7779}\x{777A}\x{777B}\x{777C}\x{777D}\x{777E}\x{777F}\x{7780}' - . '\x{7781}\x{7782}\x{7783}\x{7784}\x{7785}\x{7786}\x{7787}\x{7788}\x{7789}' - . '\x{778A}\x{778B}\x{778C}\x{778D}\x{778E}\x{778F}\x{7790}\x{7791}\x{7792}' - . '\x{7793}\x{7794}\x{7795}\x{7797}\x{7798}\x{7799}\x{779A}\x{779B}\x{779C}' - . '\x{779D}\x{779E}\x{779F}\x{77A0}\x{77A1}\x{77A2}\x{77A3}\x{77A5}\x{77A6}' - . '\x{77A7}\x{77A8}\x{77A9}\x{77AA}\x{77AB}\x{77AC}\x{77AD}\x{77AE}\x{77AF}' - . '\x{77B0}\x{77B1}\x{77B2}\x{77B3}\x{77B4}\x{77B5}\x{77B6}\x{77B7}\x{77B8}' - . '\x{77B9}\x{77BA}\x{77BB}\x{77BC}\x{77BD}\x{77BF}\x{77C0}\x{77C2}\x{77C3}' - . '\x{77C4}\x{77C5}\x{77C6}\x{77C7}\x{77C8}\x{77C9}\x{77CA}\x{77CB}\x{77CC}' - . '\x{77CD}\x{77CE}\x{77CF}\x{77D0}\x{77D1}\x{77D3}\x{77D4}\x{77D5}\x{77D6}' - . '\x{77D7}\x{77D8}\x{77D9}\x{77DA}\x{77DB}\x{77DC}\x{77DE}\x{77DF}\x{77E0}' - . '\x{77E1}\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E8}\x{77E9}\x{77EA}\x{77EB}' - . '\x{77EC}\x{77ED}\x{77EE}\x{77EF}\x{77F0}\x{77F1}\x{77F2}\x{77F3}\x{77F6}' - . '\x{77F7}\x{77F8}\x{77F9}\x{77FA}\x{77FB}\x{77FC}\x{77FD}\x{77FE}\x{77FF}' - . '\x{7800}\x{7801}\x{7802}\x{7803}\x{7804}\x{7805}\x{7806}\x{7808}\x{7809}' - . '\x{780A}\x{780B}\x{780C}\x{780D}\x{780E}\x{780F}\x{7810}\x{7811}\x{7812}' - . '\x{7813}\x{7814}\x{7815}\x{7816}\x{7817}\x{7818}\x{7819}\x{781A}\x{781B}' - . '\x{781C}\x{781D}\x{781E}\x{781F}\x{7820}\x{7821}\x{7822}\x{7823}\x{7825}' - . '\x{7826}\x{7827}\x{7828}\x{7829}\x{782A}\x{782B}\x{782C}\x{782D}\x{782E}' - . '\x{782F}\x{7830}\x{7831}\x{7832}\x{7833}\x{7834}\x{7835}\x{7837}\x{7838}' - . '\x{7839}\x{783A}\x{783B}\x{783C}\x{783D}\x{783E}\x{7840}\x{7841}\x{7843}' - . '\x{7844}\x{7845}\x{7847}\x{7848}\x{7849}\x{784A}\x{784C}\x{784D}\x{784E}' - . '\x{7850}\x{7851}\x{7852}\x{7853}\x{7854}\x{7855}\x{7856}\x{7857}\x{7858}' - . '\x{7859}\x{785A}\x{785B}\x{785C}\x{785D}\x{785E}\x{785F}\x{7860}\x{7861}' - . '\x{7862}\x{7863}\x{7864}\x{7865}\x{7866}\x{7867}\x{7868}\x{7869}\x{786A}' - . '\x{786B}\x{786C}\x{786D}\x{786E}\x{786F}\x{7870}\x{7871}\x{7872}\x{7873}' - . '\x{7874}\x{7875}\x{7877}\x{7878}\x{7879}\x{787A}\x{787B}\x{787C}\x{787D}' - . '\x{787E}\x{787F}\x{7880}\x{7881}\x{7882}\x{7883}\x{7884}\x{7885}\x{7886}' - . '\x{7887}\x{7889}\x{788A}\x{788B}\x{788C}\x{788D}\x{788E}\x{788F}\x{7890}' - . '\x{7891}\x{7892}\x{7893}\x{7894}\x{7895}\x{7896}\x{7897}\x{7898}\x{7899}' - . '\x{789A}\x{789B}\x{789C}\x{789D}\x{789E}\x{789F}\x{78A0}\x{78A1}\x{78A2}' - . '\x{78A3}\x{78A4}\x{78A5}\x{78A6}\x{78A7}\x{78A8}\x{78A9}\x{78AA}\x{78AB}' - . '\x{78AC}\x{78AD}\x{78AE}\x{78AF}\x{78B0}\x{78B1}\x{78B2}\x{78B3}\x{78B4}' - . '\x{78B5}\x{78B6}\x{78B7}\x{78B8}\x{78B9}\x{78BA}\x{78BB}\x{78BC}\x{78BD}' - . '\x{78BE}\x{78BF}\x{78C0}\x{78C1}\x{78C3}\x{78C4}\x{78C5}\x{78C6}\x{78C8}' - . '\x{78C9}\x{78CA}\x{78CB}\x{78CC}\x{78CD}\x{78CE}\x{78CF}\x{78D0}\x{78D1}' - . '\x{78D3}\x{78D4}\x{78D5}\x{78D6}\x{78D7}\x{78D8}\x{78D9}\x{78DA}\x{78DB}' - . '\x{78DC}\x{78DD}\x{78DE}\x{78DF}\x{78E0}\x{78E1}\x{78E2}\x{78E3}\x{78E4}' - . '\x{78E5}\x{78E6}\x{78E7}\x{78E8}\x{78E9}\x{78EA}\x{78EB}\x{78EC}\x{78ED}' - . '\x{78EE}\x{78EF}\x{78F1}\x{78F2}\x{78F3}\x{78F4}\x{78F5}\x{78F6}\x{78F7}' - . '\x{78F9}\x{78FA}\x{78FB}\x{78FC}\x{78FD}\x{78FE}\x{78FF}\x{7901}\x{7902}' - . '\x{7903}\x{7904}\x{7905}\x{7906}\x{7907}\x{7909}\x{790A}\x{790B}\x{790C}' - . '\x{790E}\x{790F}\x{7910}\x{7911}\x{7912}\x{7913}\x{7914}\x{7916}\x{7917}' - . '\x{7918}\x{7919}\x{791A}\x{791B}\x{791C}\x{791D}\x{791E}\x{7921}\x{7922}' - . '\x{7923}\x{7924}\x{7925}\x{7926}\x{7927}\x{7928}\x{7929}\x{792A}\x{792B}' - . '\x{792C}\x{792D}\x{792E}\x{792F}\x{7930}\x{7931}\x{7933}\x{7934}\x{7935}' - . '\x{7937}\x{7938}\x{7939}\x{793A}\x{793B}\x{793C}\x{793D}\x{793E}\x{793F}' - . '\x{7940}\x{7941}\x{7942}\x{7943}\x{7944}\x{7945}\x{7946}\x{7947}\x{7948}' - . '\x{7949}\x{794A}\x{794B}\x{794C}\x{794D}\x{794E}\x{794F}\x{7950}\x{7951}' - . '\x{7952}\x{7953}\x{7954}\x{7955}\x{7956}\x{7957}\x{7958}\x{795A}\x{795B}' - . '\x{795C}\x{795D}\x{795E}\x{795F}\x{7960}\x{7961}\x{7962}\x{7963}\x{7964}' - . '\x{7965}\x{7966}\x{7967}\x{7968}\x{7969}\x{796A}\x{796B}\x{796D}\x{796F}' - . '\x{7970}\x{7971}\x{7972}\x{7973}\x{7974}\x{7977}\x{7978}\x{7979}\x{797A}' - . '\x{797B}\x{797C}\x{797D}\x{797E}\x{797F}\x{7980}\x{7981}\x{7982}\x{7983}' - . '\x{7984}\x{7985}\x{7988}\x{7989}\x{798A}\x{798B}\x{798C}\x{798D}\x{798E}' - . '\x{798F}\x{7990}\x{7991}\x{7992}\x{7993}\x{7994}\x{7995}\x{7996}\x{7997}' - . '\x{7998}\x{7999}\x{799A}\x{799B}\x{799C}\x{799F}\x{79A0}\x{79A1}\x{79A2}' - . '\x{79A3}\x{79A4}\x{79A5}\x{79A6}\x{79A7}\x{79A8}\x{79AA}\x{79AB}\x{79AC}' - . '\x{79AD}\x{79AE}\x{79AF}\x{79B0}\x{79B1}\x{79B2}\x{79B3}\x{79B4}\x{79B5}' - . '\x{79B6}\x{79B7}\x{79B8}\x{79B9}\x{79BA}\x{79BB}\x{79BD}\x{79BE}\x{79BF}' - . '\x{79C0}\x{79C1}\x{79C2}\x{79C3}\x{79C5}\x{79C6}\x{79C8}\x{79C9}\x{79CA}' - . '\x{79CB}\x{79CD}\x{79CE}\x{79CF}\x{79D0}\x{79D1}\x{79D2}\x{79D3}\x{79D5}' - . '\x{79D6}\x{79D8}\x{79D9}\x{79DA}\x{79DB}\x{79DC}\x{79DD}\x{79DE}\x{79DF}' - . '\x{79E0}\x{79E1}\x{79E2}\x{79E3}\x{79E4}\x{79E5}\x{79E6}\x{79E7}\x{79E8}' - . '\x{79E9}\x{79EA}\x{79EB}\x{79EC}\x{79ED}\x{79EE}\x{79EF}\x{79F0}\x{79F1}' - . '\x{79F2}\x{79F3}\x{79F4}\x{79F5}\x{79F6}\x{79F7}\x{79F8}\x{79F9}\x{79FA}' - . '\x{79FB}\x{79FC}\x{79FD}\x{79FE}\x{79FF}\x{7A00}\x{7A02}\x{7A03}\x{7A04}' - . '\x{7A05}\x{7A06}\x{7A08}\x{7A0A}\x{7A0B}\x{7A0C}\x{7A0D}\x{7A0E}\x{7A0F}' - . '\x{7A10}\x{7A11}\x{7A12}\x{7A13}\x{7A14}\x{7A15}\x{7A16}\x{7A17}\x{7A18}' - . '\x{7A19}\x{7A1A}\x{7A1B}\x{7A1C}\x{7A1D}\x{7A1E}\x{7A1F}\x{7A20}\x{7A21}' - . '\x{7A22}\x{7A23}\x{7A24}\x{7A25}\x{7A26}\x{7A27}\x{7A28}\x{7A29}\x{7A2A}' - . '\x{7A2B}\x{7A2D}\x{7A2E}\x{7A2F}\x{7A30}\x{7A31}\x{7A32}\x{7A33}\x{7A34}' - . '\x{7A35}\x{7A37}\x{7A39}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' - . '\x{7A41}\x{7A42}\x{7A43}\x{7A44}\x{7A45}\x{7A46}\x{7A47}\x{7A48}\x{7A49}' - . '\x{7A4A}\x{7A4B}\x{7A4C}\x{7A4D}\x{7A4E}\x{7A50}\x{7A51}\x{7A52}\x{7A53}' - . '\x{7A54}\x{7A55}\x{7A56}\x{7A57}\x{7A58}\x{7A59}\x{7A5A}\x{7A5B}\x{7A5C}' - . '\x{7A5D}\x{7A5E}\x{7A5F}\x{7A60}\x{7A61}\x{7A62}\x{7A65}\x{7A66}\x{7A67}' - . '\x{7A68}\x{7A69}\x{7A6B}\x{7A6C}\x{7A6D}\x{7A6E}\x{7A70}\x{7A71}\x{7A72}' - . '\x{7A73}\x{7A74}\x{7A75}\x{7A76}\x{7A77}\x{7A78}\x{7A79}\x{7A7A}\x{7A7B}' - . '\x{7A7C}\x{7A7D}\x{7A7E}\x{7A7F}\x{7A80}\x{7A81}\x{7A83}\x{7A84}\x{7A85}' - . '\x{7A86}\x{7A87}\x{7A88}\x{7A89}\x{7A8A}\x{7A8B}\x{7A8C}\x{7A8D}\x{7A8E}' - . '\x{7A8F}\x{7A90}\x{7A91}\x{7A92}\x{7A93}\x{7A94}\x{7A95}\x{7A96}\x{7A97}' - . '\x{7A98}\x{7A99}\x{7A9C}\x{7A9D}\x{7A9E}\x{7A9F}\x{7AA0}\x{7AA1}\x{7AA2}' - . '\x{7AA3}\x{7AA4}\x{7AA5}\x{7AA6}\x{7AA7}\x{7AA8}\x{7AA9}\x{7AAA}\x{7AAB}' - . '\x{7AAC}\x{7AAD}\x{7AAE}\x{7AAF}\x{7AB0}\x{7AB1}\x{7AB2}\x{7AB3}\x{7AB4}' - . '\x{7AB5}\x{7AB6}\x{7AB7}\x{7AB8}\x{7ABA}\x{7ABE}\x{7ABF}\x{7AC0}\x{7AC1}' - . '\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}\x{7AC9}\x{7ACA}\x{7ACB}\x{7ACC}\x{7ACD}' - . '\x{7ACE}\x{7ACF}\x{7AD0}\x{7AD1}\x{7AD2}\x{7AD3}\x{7AD4}\x{7AD5}\x{7AD6}' - . '\x{7AD8}\x{7AD9}\x{7ADB}\x{7ADC}\x{7ADD}\x{7ADE}\x{7ADF}\x{7AE0}\x{7AE1}' - . '\x{7AE2}\x{7AE3}\x{7AE4}\x{7AE5}\x{7AE6}\x{7AE7}\x{7AE8}\x{7AEA}\x{7AEB}' - . '\x{7AEC}\x{7AED}\x{7AEE}\x{7AEF}\x{7AF0}\x{7AF1}\x{7AF2}\x{7AF3}\x{7AF4}' - . '\x{7AF6}\x{7AF7}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFB}\x{7AFD}\x{7AFE}\x{7AFF}' - . '\x{7B00}\x{7B01}\x{7B02}\x{7B03}\x{7B04}\x{7B05}\x{7B06}\x{7B08}\x{7B09}' - . '\x{7B0A}\x{7B0B}\x{7B0C}\x{7B0D}\x{7B0E}\x{7B0F}\x{7B10}\x{7B11}\x{7B12}' - . '\x{7B13}\x{7B14}\x{7B15}\x{7B16}\x{7B17}\x{7B18}\x{7B19}\x{7B1A}\x{7B1B}' - . '\x{7B1C}\x{7B1D}\x{7B1E}\x{7B20}\x{7B21}\x{7B22}\x{7B23}\x{7B24}\x{7B25}' - . '\x{7B26}\x{7B28}\x{7B2A}\x{7B2B}\x{7B2C}\x{7B2D}\x{7B2E}\x{7B2F}\x{7B30}' - . '\x{7B31}\x{7B32}\x{7B33}\x{7B34}\x{7B35}\x{7B36}\x{7B37}\x{7B38}\x{7B39}' - . '\x{7B3A}\x{7B3B}\x{7B3C}\x{7B3D}\x{7B3E}\x{7B3F}\x{7B40}\x{7B41}\x{7B43}' - . '\x{7B44}\x{7B45}\x{7B46}\x{7B47}\x{7B48}\x{7B49}\x{7B4A}\x{7B4B}\x{7B4C}' - . '\x{7B4D}\x{7B4E}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B55}\x{7B56}' - . '\x{7B57}\x{7B58}\x{7B59}\x{7B5A}\x{7B5B}\x{7B5C}\x{7B5D}\x{7B5E}\x{7B5F}' - . '\x{7B60}\x{7B61}\x{7B62}\x{7B63}\x{7B64}\x{7B65}\x{7B66}\x{7B67}\x{7B68}' - . '\x{7B69}\x{7B6A}\x{7B6B}\x{7B6C}\x{7B6D}\x{7B6E}\x{7B70}\x{7B71}\x{7B72}' - . '\x{7B73}\x{7B74}\x{7B75}\x{7B76}\x{7B77}\x{7B78}\x{7B79}\x{7B7B}\x{7B7C}' - . '\x{7B7D}\x{7B7E}\x{7B7F}\x{7B80}\x{7B81}\x{7B82}\x{7B83}\x{7B84}\x{7B85}' - . '\x{7B87}\x{7B88}\x{7B89}\x{7B8A}\x{7B8B}\x{7B8C}\x{7B8D}\x{7B8E}\x{7B8F}' - . '\x{7B90}\x{7B91}\x{7B93}\x{7B94}\x{7B95}\x{7B96}\x{7B97}\x{7B98}\x{7B99}' - . '\x{7B9A}\x{7B9B}\x{7B9C}\x{7B9D}\x{7B9E}\x{7B9F}\x{7BA0}\x{7BA1}\x{7BA2}' - . '\x{7BA4}\x{7BA6}\x{7BA7}\x{7BA8}\x{7BA9}\x{7BAA}\x{7BAB}\x{7BAC}\x{7BAD}' - . '\x{7BAE}\x{7BAF}\x{7BB1}\x{7BB3}\x{7BB4}\x{7BB5}\x{7BB6}\x{7BB7}\x{7BB8}' - . '\x{7BB9}\x{7BBA}\x{7BBB}\x{7BBC}\x{7BBD}\x{7BBE}\x{7BBF}\x{7BC0}\x{7BC1}' - . '\x{7BC2}\x{7BC3}\x{7BC4}\x{7BC5}\x{7BC6}\x{7BC7}\x{7BC8}\x{7BC9}\x{7BCA}' - . '\x{7BCB}\x{7BCC}\x{7BCD}\x{7BCE}\x{7BD0}\x{7BD1}\x{7BD2}\x{7BD3}\x{7BD4}' - . '\x{7BD5}\x{7BD6}\x{7BD7}\x{7BD8}\x{7BD9}\x{7BDA}\x{7BDB}\x{7BDC}\x{7BDD}' - . '\x{7BDE}\x{7BDF}\x{7BE0}\x{7BE1}\x{7BE2}\x{7BE3}\x{7BE4}\x{7BE5}\x{7BE6}' - . '\x{7BE7}\x{7BE8}\x{7BE9}\x{7BEA}\x{7BEB}\x{7BEC}\x{7BED}\x{7BEE}\x{7BEF}' - . '\x{7BF0}\x{7BF1}\x{7BF2}\x{7BF3}\x{7BF4}\x{7BF5}\x{7BF6}\x{7BF7}\x{7BF8}' - . '\x{7BF9}\x{7BFB}\x{7BFC}\x{7BFD}\x{7BFE}\x{7BFF}\x{7C00}\x{7C01}\x{7C02}' - . '\x{7C03}\x{7C04}\x{7C05}\x{7C06}\x{7C07}\x{7C08}\x{7C09}\x{7C0A}\x{7C0B}' - . '\x{7C0C}\x{7C0D}\x{7C0E}\x{7C0F}\x{7C10}\x{7C11}\x{7C12}\x{7C13}\x{7C15}' - . '\x{7C16}\x{7C17}\x{7C18}\x{7C19}\x{7C1A}\x{7C1C}\x{7C1D}\x{7C1E}\x{7C1F}' - . '\x{7C20}\x{7C21}\x{7C22}\x{7C23}\x{7C24}\x{7C25}\x{7C26}\x{7C27}\x{7C28}' - . '\x{7C29}\x{7C2A}\x{7C2B}\x{7C2C}\x{7C2D}\x{7C30}\x{7C31}\x{7C32}\x{7C33}' - . '\x{7C34}\x{7C35}\x{7C36}\x{7C37}\x{7C38}\x{7C39}\x{7C3A}\x{7C3B}\x{7C3C}' - . '\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C41}\x{7C42}\x{7C43}\x{7C44}\x{7C45}' - . '\x{7C46}\x{7C47}\x{7C48}\x{7C49}\x{7C4A}\x{7C4B}\x{7C4C}\x{7C4D}\x{7C4E}' - . '\x{7C50}\x{7C51}\x{7C53}\x{7C54}\x{7C56}\x{7C57}\x{7C58}\x{7C59}\x{7C5A}' - . '\x{7C5B}\x{7C5C}\x{7C5E}\x{7C5F}\x{7C60}\x{7C61}\x{7C62}\x{7C63}\x{7C64}' - . '\x{7C65}\x{7C66}\x{7C67}\x{7C68}\x{7C69}\x{7C6A}\x{7C6B}\x{7C6C}\x{7C6D}' - . '\x{7C6E}\x{7C6F}\x{7C70}\x{7C71}\x{7C72}\x{7C73}\x{7C74}\x{7C75}\x{7C77}' - . '\x{7C78}\x{7C79}\x{7C7A}\x{7C7B}\x{7C7C}\x{7C7D}\x{7C7E}\x{7C7F}\x{7C80}' - . '\x{7C81}\x{7C82}\x{7C84}\x{7C85}\x{7C86}\x{7C88}\x{7C89}\x{7C8A}\x{7C8B}' - . '\x{7C8C}\x{7C8D}\x{7C8E}\x{7C8F}\x{7C90}\x{7C91}\x{7C92}\x{7C94}\x{7C95}' - . '\x{7C96}\x{7C97}\x{7C98}\x{7C99}\x{7C9B}\x{7C9C}\x{7C9D}\x{7C9E}\x{7C9F}' - . '\x{7CA0}\x{7CA1}\x{7CA2}\x{7CA3}\x{7CA4}\x{7CA5}\x{7CA6}\x{7CA7}\x{7CA8}' - . '\x{7CA9}\x{7CAA}\x{7CAD}\x{7CAE}\x{7CAF}\x{7CB0}\x{7CB1}\x{7CB2}\x{7CB3}' - . '\x{7CB4}\x{7CB5}\x{7CB6}\x{7CB7}\x{7CB8}\x{7CB9}\x{7CBA}\x{7CBB}\x{7CBC}' - . '\x{7CBD}\x{7CBE}\x{7CBF}\x{7CC0}\x{7CC1}\x{7CC2}\x{7CC3}\x{7CC4}\x{7CC5}' - . '\x{7CC6}\x{7CC7}\x{7CC8}\x{7CC9}\x{7CCA}\x{7CCB}\x{7CCC}\x{7CCD}\x{7CCE}' - . '\x{7CCF}\x{7CD0}\x{7CD1}\x{7CD2}\x{7CD4}\x{7CD5}\x{7CD6}\x{7CD7}\x{7CD8}' - . '\x{7CD9}\x{7CDC}\x{7CDD}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE4}\x{7CE7}' - . '\x{7CE8}\x{7CE9}\x{7CEA}\x{7CEB}\x{7CEC}\x{7CED}\x{7CEE}\x{7CEF}\x{7CF0}' - . '\x{7CF1}\x{7CF2}\x{7CF3}\x{7CF4}\x{7CF5}\x{7CF6}\x{7CF7}\x{7CF8}\x{7CF9}' - . '\x{7CFA}\x{7CFB}\x{7CFD}\x{7CFE}\x{7D00}\x{7D01}\x{7D02}\x{7D03}\x{7D04}' - . '\x{7D05}\x{7D06}\x{7D07}\x{7D08}\x{7D09}\x{7D0A}\x{7D0B}\x{7D0C}\x{7D0D}' - . '\x{7D0E}\x{7D0F}\x{7D10}\x{7D11}\x{7D12}\x{7D13}\x{7D14}\x{7D15}\x{7D16}' - . '\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D1D}\x{7D1E}\x{7D1F}' - . '\x{7D20}\x{7D21}\x{7D22}\x{7D24}\x{7D25}\x{7D26}\x{7D27}\x{7D28}\x{7D29}' - . '\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D31}\x{7D32}\x{7D33}\x{7D34}' - . '\x{7D35}\x{7D36}\x{7D37}\x{7D38}\x{7D39}\x{7D3A}\x{7D3B}\x{7D3C}\x{7D3D}' - . '\x{7D3E}\x{7D3F}\x{7D40}\x{7D41}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}' - . '\x{7D47}\x{7D49}\x{7D4A}\x{7D4B}\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D51}' - . '\x{7D52}\x{7D53}\x{7D54}\x{7D55}\x{7D56}\x{7D57}\x{7D58}\x{7D59}\x{7D5B}' - . '\x{7D5C}\x{7D5D}\x{7D5E}\x{7D5F}\x{7D60}\x{7D61}\x{7D62}\x{7D63}\x{7D65}' - . '\x{7D66}\x{7D67}\x{7D68}\x{7D69}\x{7D6A}\x{7D6B}\x{7D6C}\x{7D6D}\x{7D6E}' - . '\x{7D6F}\x{7D70}\x{7D71}\x{7D72}\x{7D73}\x{7D74}\x{7D75}\x{7D76}\x{7D77}' - . '\x{7D79}\x{7D7A}\x{7D7B}\x{7D7C}\x{7D7D}\x{7D7E}\x{7D7F}\x{7D80}\x{7D81}' - . '\x{7D83}\x{7D84}\x{7D85}\x{7D86}\x{7D87}\x{7D88}\x{7D89}\x{7D8A}\x{7D8B}' - . '\x{7D8C}\x{7D8D}\x{7D8E}\x{7D8F}\x{7D90}\x{7D91}\x{7D92}\x{7D93}\x{7D94}' - . '\x{7D96}\x{7D97}\x{7D99}\x{7D9B}\x{7D9C}\x{7D9D}\x{7D9E}\x{7D9F}\x{7DA0}' - . '\x{7DA1}\x{7DA2}\x{7DA3}\x{7DA5}\x{7DA6}\x{7DA7}\x{7DA9}\x{7DAA}\x{7DAB}' - . '\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}\x{7DB1}\x{7DB2}\x{7DB3}\x{7DB4}' - . '\x{7DB5}\x{7DB6}\x{7DB7}\x{7DB8}\x{7DB9}\x{7DBA}\x{7DBB}\x{7DBC}\x{7DBD}' - . '\x{7DBE}\x{7DBF}\x{7DC0}\x{7DC1}\x{7DC2}\x{7DC3}\x{7DC4}\x{7DC5}\x{7DC6}' - . '\x{7DC7}\x{7DC8}\x{7DC9}\x{7DCA}\x{7DCB}\x{7DCC}\x{7DCE}\x{7DCF}\x{7DD0}' - . '\x{7DD1}\x{7DD2}\x{7DD4}\x{7DD5}\x{7DD6}\x{7DD7}\x{7DD8}\x{7DD9}\x{7DDA}' - . '\x{7DDB}\x{7DDD}\x{7DDE}\x{7DDF}\x{7DE0}\x{7DE1}\x{7DE2}\x{7DE3}\x{7DE6}' - . '\x{7DE7}\x{7DE8}\x{7DE9}\x{7DEA}\x{7DEC}\x{7DED}\x{7DEE}\x{7DEF}\x{7DF0}' - . '\x{7DF1}\x{7DF2}\x{7DF3}\x{7DF4}\x{7DF5}\x{7DF6}\x{7DF7}\x{7DF8}\x{7DF9}' - . '\x{7DFA}\x{7DFB}\x{7DFC}\x{7E00}\x{7E01}\x{7E02}\x{7E03}\x{7E04}\x{7E05}' - . '\x{7E06}\x{7E07}\x{7E08}\x{7E09}\x{7E0A}\x{7E0B}\x{7E0C}\x{7E0D}\x{7E0E}' - . '\x{7E0F}\x{7E10}\x{7E11}\x{7E12}\x{7E13}\x{7E14}\x{7E15}\x{7E16}\x{7E17}' - . '\x{7E19}\x{7E1A}\x{7E1B}\x{7E1C}\x{7E1D}\x{7E1E}\x{7E1F}\x{7E20}\x{7E21}' - . '\x{7E22}\x{7E23}\x{7E24}\x{7E25}\x{7E26}\x{7E27}\x{7E28}\x{7E29}\x{7E2A}' - . '\x{7E2B}\x{7E2C}\x{7E2D}\x{7E2E}\x{7E2F}\x{7E30}\x{7E31}\x{7E32}\x{7E33}' - . '\x{7E34}\x{7E35}\x{7E36}\x{7E37}\x{7E38}\x{7E39}\x{7E3A}\x{7E3B}\x{7E3C}' - . '\x{7E3D}\x{7E3E}\x{7E3F}\x{7E40}\x{7E41}\x{7E42}\x{7E43}\x{7E44}\x{7E45}' - . '\x{7E46}\x{7E47}\x{7E48}\x{7E49}\x{7E4C}\x{7E4D}\x{7E4E}\x{7E4F}\x{7E50}' - . '\x{7E51}\x{7E52}\x{7E53}\x{7E54}\x{7E55}\x{7E56}\x{7E57}\x{7E58}\x{7E59}' - . '\x{7E5A}\x{7E5C}\x{7E5D}\x{7E5E}\x{7E5F}\x{7E60}\x{7E61}\x{7E62}\x{7E63}' - . '\x{7E65}\x{7E66}\x{7E67}\x{7E68}\x{7E69}\x{7E6A}\x{7E6B}\x{7E6C}\x{7E6D}' - . '\x{7E6E}\x{7E6F}\x{7E70}\x{7E71}\x{7E72}\x{7E73}\x{7E74}\x{7E75}\x{7E76}' - . '\x{7E77}\x{7E78}\x{7E79}\x{7E7A}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7E}\x{7E7F}' - . '\x{7E80}\x{7E81}\x{7E82}\x{7E83}\x{7E84}\x{7E85}\x{7E86}\x{7E87}\x{7E88}' - . '\x{7E89}\x{7E8A}\x{7E8B}\x{7E8C}\x{7E8D}\x{7E8E}\x{7E8F}\x{7E90}\x{7E91}' - . '\x{7E92}\x{7E93}\x{7E94}\x{7E95}\x{7E96}\x{7E97}\x{7E98}\x{7E99}\x{7E9A}' - . '\x{7E9B}\x{7E9C}\x{7E9E}\x{7E9F}\x{7EA0}\x{7EA1}\x{7EA2}\x{7EA3}\x{7EA4}' - . '\x{7EA5}\x{7EA6}\x{7EA7}\x{7EA8}\x{7EA9}\x{7EAA}\x{7EAB}\x{7EAC}\x{7EAD}' - . '\x{7EAE}\x{7EAF}\x{7EB0}\x{7EB1}\x{7EB2}\x{7EB3}\x{7EB4}\x{7EB5}\x{7EB6}' - . '\x{7EB7}\x{7EB8}\x{7EB9}\x{7EBA}\x{7EBB}\x{7EBC}\x{7EBD}\x{7EBE}\x{7EBF}' - . '\x{7EC0}\x{7EC1}\x{7EC2}\x{7EC3}\x{7EC4}\x{7EC5}\x{7EC6}\x{7EC7}\x{7EC8}' - . '\x{7EC9}\x{7ECA}\x{7ECB}\x{7ECC}\x{7ECD}\x{7ECE}\x{7ECF}\x{7ED0}\x{7ED1}' - . '\x{7ED2}\x{7ED3}\x{7ED4}\x{7ED5}\x{7ED6}\x{7ED7}\x{7ED8}\x{7ED9}\x{7EDA}' - . '\x{7EDB}\x{7EDC}\x{7EDD}\x{7EDE}\x{7EDF}\x{7EE0}\x{7EE1}\x{7EE2}\x{7EE3}' - . '\x{7EE4}\x{7EE5}\x{7EE6}\x{7EE7}\x{7EE8}\x{7EE9}\x{7EEA}\x{7EEB}\x{7EEC}' - . '\x{7EED}\x{7EEE}\x{7EEF}\x{7EF0}\x{7EF1}\x{7EF2}\x{7EF3}\x{7EF4}\x{7EF5}' - . '\x{7EF6}\x{7EF7}\x{7EF8}\x{7EF9}\x{7EFA}\x{7EFB}\x{7EFC}\x{7EFD}\x{7EFE}' - . '\x{7EFF}\x{7F00}\x{7F01}\x{7F02}\x{7F03}\x{7F04}\x{7F05}\x{7F06}\x{7F07}' - . '\x{7F08}\x{7F09}\x{7F0A}\x{7F0B}\x{7F0C}\x{7F0D}\x{7F0E}\x{7F0F}\x{7F10}' - . '\x{7F11}\x{7F12}\x{7F13}\x{7F14}\x{7F15}\x{7F16}\x{7F17}\x{7F18}\x{7F19}' - . '\x{7F1A}\x{7F1B}\x{7F1C}\x{7F1D}\x{7F1E}\x{7F1F}\x{7F20}\x{7F21}\x{7F22}' - . '\x{7F23}\x{7F24}\x{7F25}\x{7F26}\x{7F27}\x{7F28}\x{7F29}\x{7F2A}\x{7F2B}' - . '\x{7F2C}\x{7F2D}\x{7F2E}\x{7F2F}\x{7F30}\x{7F31}\x{7F32}\x{7F33}\x{7F34}' - . '\x{7F35}\x{7F36}\x{7F37}\x{7F38}\x{7F39}\x{7F3A}\x{7F3D}\x{7F3E}\x{7F3F}' - . '\x{7F40}\x{7F42}\x{7F43}\x{7F44}\x{7F45}\x{7F47}\x{7F48}\x{7F49}\x{7F4A}' - . '\x{7F4B}\x{7F4C}\x{7F4D}\x{7F4E}\x{7F4F}\x{7F50}\x{7F51}\x{7F52}\x{7F53}' - . '\x{7F54}\x{7F55}\x{7F56}\x{7F57}\x{7F58}\x{7F5A}\x{7F5B}\x{7F5C}\x{7F5D}' - . '\x{7F5E}\x{7F5F}\x{7F60}\x{7F61}\x{7F62}\x{7F63}\x{7F64}\x{7F65}\x{7F66}' - . '\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6C}\x{7F6D}\x{7F6E}\x{7F6F}' - . '\x{7F70}\x{7F71}\x{7F72}\x{7F73}\x{7F74}\x{7F75}\x{7F76}\x{7F77}\x{7F78}' - . '\x{7F79}\x{7F7A}\x{7F7B}\x{7F7C}\x{7F7D}\x{7F7E}\x{7F7F}\x{7F80}\x{7F81}' - . '\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}\x{7F88}\x{7F89}\x{7F8A}\x{7F8B}' - . '\x{7F8C}\x{7F8D}\x{7F8E}\x{7F8F}\x{7F91}\x{7F92}\x{7F93}\x{7F94}\x{7F95}' - . '\x{7F96}\x{7F98}\x{7F9A}\x{7F9B}\x{7F9C}\x{7F9D}\x{7F9E}\x{7F9F}\x{7FA0}' - . '\x{7FA1}\x{7FA2}\x{7FA3}\x{7FA4}\x{7FA5}\x{7FA6}\x{7FA7}\x{7FA8}\x{7FA9}' - . '\x{7FAA}\x{7FAB}\x{7FAC}\x{7FAD}\x{7FAE}\x{7FAF}\x{7FB0}\x{7FB1}\x{7FB2}' - . '\x{7FB3}\x{7FB5}\x{7FB6}\x{7FB7}\x{7FB8}\x{7FB9}\x{7FBA}\x{7FBB}\x{7FBC}' - . '\x{7FBD}\x{7FBE}\x{7FBF}\x{7FC0}\x{7FC1}\x{7FC2}\x{7FC3}\x{7FC4}\x{7FC5}' - . '\x{7FC6}\x{7FC7}\x{7FC8}\x{7FC9}\x{7FCA}\x{7FCB}\x{7FCC}\x{7FCD}\x{7FCE}' - . '\x{7FCF}\x{7FD0}\x{7FD1}\x{7FD2}\x{7FD3}\x{7FD4}\x{7FD5}\x{7FD7}\x{7FD8}' - . '\x{7FD9}\x{7FDA}\x{7FDB}\x{7FDC}\x{7FDE}\x{7FDF}\x{7FE0}\x{7FE1}\x{7FE2}' - . '\x{7FE3}\x{7FE5}\x{7FE6}\x{7FE7}\x{7FE8}\x{7FE9}\x{7FEA}\x{7FEB}\x{7FEC}' - . '\x{7FED}\x{7FEE}\x{7FEF}\x{7FF0}\x{7FF1}\x{7FF2}\x{7FF3}\x{7FF4}\x{7FF5}' - . '\x{7FF6}\x{7FF7}\x{7FF8}\x{7FF9}\x{7FFA}\x{7FFB}\x{7FFC}\x{7FFD}\x{7FFE}' - . '\x{7FFF}\x{8000}\x{8001}\x{8002}\x{8003}\x{8004}\x{8005}\x{8006}\x{8007}' - . '\x{8008}\x{8009}\x{800B}\x{800C}\x{800D}\x{800E}\x{800F}\x{8010}\x{8011}' - . '\x{8012}\x{8013}\x{8014}\x{8015}\x{8016}\x{8017}\x{8018}\x{8019}\x{801A}' - . '\x{801B}\x{801C}\x{801D}\x{801E}\x{801F}\x{8020}\x{8021}\x{8022}\x{8023}' - . '\x{8024}\x{8025}\x{8026}\x{8027}\x{8028}\x{8029}\x{802A}\x{802B}\x{802C}' - . '\x{802D}\x{802E}\x{8030}\x{8031}\x{8032}\x{8033}\x{8034}\x{8035}\x{8036}' - . '\x{8037}\x{8038}\x{8039}\x{803A}\x{803B}\x{803D}\x{803E}\x{803F}\x{8041}' - . '\x{8042}\x{8043}\x{8044}\x{8045}\x{8046}\x{8047}\x{8048}\x{8049}\x{804A}' - . '\x{804B}\x{804C}\x{804D}\x{804E}\x{804F}\x{8050}\x{8051}\x{8052}\x{8053}' - . '\x{8054}\x{8055}\x{8056}\x{8057}\x{8058}\x{8059}\x{805A}\x{805B}\x{805C}' - . '\x{805D}\x{805E}\x{805F}\x{8060}\x{8061}\x{8062}\x{8063}\x{8064}\x{8065}' - . '\x{8067}\x{8068}\x{8069}\x{806A}\x{806B}\x{806C}\x{806D}\x{806E}\x{806F}' - . '\x{8070}\x{8071}\x{8072}\x{8073}\x{8074}\x{8075}\x{8076}\x{8077}\x{8078}' - . '\x{8079}\x{807A}\x{807B}\x{807C}\x{807D}\x{807E}\x{807F}\x{8080}\x{8081}' - . '\x{8082}\x{8083}\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808A}\x{808B}' - . '\x{808C}\x{808D}\x{808F}\x{8090}\x{8091}\x{8092}\x{8093}\x{8095}\x{8096}' - . '\x{8097}\x{8098}\x{8099}\x{809A}\x{809B}\x{809C}\x{809D}\x{809E}\x{809F}' - . '\x{80A0}\x{80A1}\x{80A2}\x{80A3}\x{80A4}\x{80A5}\x{80A9}\x{80AA}\x{80AB}' - . '\x{80AD}\x{80AE}\x{80AF}\x{80B0}\x{80B1}\x{80B2}\x{80B4}\x{80B5}\x{80B6}' - . '\x{80B7}\x{80B8}\x{80BA}\x{80BB}\x{80BC}\x{80BD}\x{80BE}\x{80BF}\x{80C0}' - . '\x{80C1}\x{80C2}\x{80C3}\x{80C4}\x{80C5}\x{80C6}\x{80C7}\x{80C8}\x{80C9}' - . '\x{80CA}\x{80CB}\x{80CC}\x{80CD}\x{80CE}\x{80CF}\x{80D0}\x{80D1}\x{80D2}' - . '\x{80D3}\x{80D4}\x{80D5}\x{80D6}\x{80D7}\x{80D8}\x{80D9}\x{80DA}\x{80DB}' - . '\x{80DC}\x{80DD}\x{80DE}\x{80E0}\x{80E1}\x{80E2}\x{80E3}\x{80E4}\x{80E5}' - . '\x{80E6}\x{80E7}\x{80E8}\x{80E9}\x{80EA}\x{80EB}\x{80EC}\x{80ED}\x{80EE}' - . '\x{80EF}\x{80F0}\x{80F1}\x{80F2}\x{80F3}\x{80F4}\x{80F5}\x{80F6}\x{80F7}' - . '\x{80F8}\x{80F9}\x{80FA}\x{80FB}\x{80FC}\x{80FD}\x{80FE}\x{80FF}\x{8100}' - . '\x{8101}\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{810B}' - . '\x{810C}\x{810D}\x{810E}\x{810F}\x{8110}\x{8111}\x{8112}\x{8113}\x{8114}' - . '\x{8115}\x{8116}\x{8118}\x{8119}\x{811A}\x{811B}\x{811C}\x{811D}\x{811E}' - . '\x{811F}\x{8120}\x{8121}\x{8122}\x{8123}\x{8124}\x{8125}\x{8126}\x{8127}' - . '\x{8128}\x{8129}\x{812A}\x{812B}\x{812C}\x{812D}\x{812E}\x{812F}\x{8130}' - . '\x{8131}\x{8132}\x{8136}\x{8137}\x{8138}\x{8139}\x{813A}\x{813B}\x{813C}' - . '\x{813D}\x{813E}\x{813F}\x{8140}\x{8141}\x{8142}\x{8143}\x{8144}\x{8145}' - . '\x{8146}\x{8147}\x{8148}\x{8149}\x{814A}\x{814B}\x{814C}\x{814D}\x{814E}' - . '\x{814F}\x{8150}\x{8151}\x{8152}\x{8153}\x{8154}\x{8155}\x{8156}\x{8157}' - . '\x{8158}\x{8159}\x{815A}\x{815B}\x{815C}\x{815D}\x{815E}\x{8160}\x{8161}' - . '\x{8162}\x{8163}\x{8164}\x{8165}\x{8166}\x{8167}\x{8168}\x{8169}\x{816A}' - . '\x{816B}\x{816C}\x{816D}\x{816E}\x{816F}\x{8170}\x{8171}\x{8172}\x{8173}' - . '\x{8174}\x{8175}\x{8176}\x{8177}\x{8178}\x{8179}\x{817A}\x{817B}\x{817C}' - . '\x{817D}\x{817E}\x{817F}\x{8180}\x{8181}\x{8182}\x{8183}\x{8185}\x{8186}' - . '\x{8187}\x{8188}\x{8189}\x{818A}\x{818B}\x{818C}\x{818D}\x{818E}\x{818F}' - . '\x{8191}\x{8192}\x{8193}\x{8194}\x{8195}\x{8197}\x{8198}\x{8199}\x{819A}' - . '\x{819B}\x{819C}\x{819D}\x{819E}\x{819F}\x{81A0}\x{81A1}\x{81A2}\x{81A3}' - . '\x{81A4}\x{81A5}\x{81A6}\x{81A7}\x{81A8}\x{81A9}\x{81AA}\x{81AB}\x{81AC}' - . '\x{81AD}\x{81AE}\x{81AF}\x{81B0}\x{81B1}\x{81B2}\x{81B3}\x{81B4}\x{81B5}' - . '\x{81B6}\x{81B7}\x{81B8}\x{81B9}\x{81BA}\x{81BB}\x{81BC}\x{81BD}\x{81BE}' - . '\x{81BF}\x{81C0}\x{81C1}\x{81C2}\x{81C3}\x{81C4}\x{81C5}\x{81C6}\x{81C7}' - . '\x{81C8}\x{81C9}\x{81CA}\x{81CC}\x{81CD}\x{81CE}\x{81CF}\x{81D0}\x{81D1}' - . '\x{81D2}\x{81D4}\x{81D5}\x{81D6}\x{81D7}\x{81D8}\x{81D9}\x{81DA}\x{81DB}' - . '\x{81DC}\x{81DD}\x{81DE}\x{81DF}\x{81E0}\x{81E1}\x{81E2}\x{81E3}\x{81E5}' - . '\x{81E6}\x{81E7}\x{81E8}\x{81E9}\x{81EA}\x{81EB}\x{81EC}\x{81ED}\x{81EE}' - . '\x{81F1}\x{81F2}\x{81F3}\x{81F4}\x{81F5}\x{81F6}\x{81F7}\x{81F8}\x{81F9}' - . '\x{81FA}\x{81FB}\x{81FC}\x{81FD}\x{81FE}\x{81FF}\x{8200}\x{8201}\x{8202}' - . '\x{8203}\x{8204}\x{8205}\x{8206}\x{8207}\x{8208}\x{8209}\x{820A}\x{820B}' - . '\x{820C}\x{820D}\x{820E}\x{820F}\x{8210}\x{8211}\x{8212}\x{8214}\x{8215}' - . '\x{8216}\x{8218}\x{8219}\x{821A}\x{821B}\x{821C}\x{821D}\x{821E}\x{821F}' - . '\x{8220}\x{8221}\x{8222}\x{8223}\x{8225}\x{8226}\x{8227}\x{8228}\x{8229}' - . '\x{822A}\x{822B}\x{822C}\x{822D}\x{822F}\x{8230}\x{8231}\x{8232}\x{8233}' - . '\x{8234}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{823A}\x{823B}\x{823C}' - . '\x{823D}\x{823E}\x{823F}\x{8240}\x{8242}\x{8243}\x{8244}\x{8245}\x{8246}' - . '\x{8247}\x{8248}\x{8249}\x{824A}\x{824B}\x{824C}\x{824D}\x{824E}\x{824F}' - . '\x{8250}\x{8251}\x{8252}\x{8253}\x{8254}\x{8255}\x{8256}\x{8257}\x{8258}' - . '\x{8259}\x{825A}\x{825B}\x{825C}\x{825D}\x{825E}\x{825F}\x{8260}\x{8261}' - . '\x{8263}\x{8264}\x{8266}\x{8267}\x{8268}\x{8269}\x{826A}\x{826B}\x{826C}' - . '\x{826D}\x{826E}\x{826F}\x{8270}\x{8271}\x{8272}\x{8273}\x{8274}\x{8275}' - . '\x{8276}\x{8277}\x{8278}\x{8279}\x{827A}\x{827B}\x{827C}\x{827D}\x{827E}' - . '\x{827F}\x{8280}\x{8281}\x{8282}\x{8283}\x{8284}\x{8285}\x{8286}\x{8287}' - . '\x{8288}\x{8289}\x{828A}\x{828B}\x{828D}\x{828E}\x{828F}\x{8290}\x{8291}' - . '\x{8292}\x{8293}\x{8294}\x{8295}\x{8296}\x{8297}\x{8298}\x{8299}\x{829A}' - . '\x{829B}\x{829C}\x{829D}\x{829E}\x{829F}\x{82A0}\x{82A1}\x{82A2}\x{82A3}' - . '\x{82A4}\x{82A5}\x{82A6}\x{82A7}\x{82A8}\x{82A9}\x{82AA}\x{82AB}\x{82AC}' - . '\x{82AD}\x{82AE}\x{82AF}\x{82B0}\x{82B1}\x{82B3}\x{82B4}\x{82B5}\x{82B6}' - . '\x{82B7}\x{82B8}\x{82B9}\x{82BA}\x{82BB}\x{82BC}\x{82BD}\x{82BE}\x{82BF}' - . '\x{82C0}\x{82C1}\x{82C2}\x{82C3}\x{82C4}\x{82C5}\x{82C6}\x{82C7}\x{82C8}' - . '\x{82C9}\x{82CA}\x{82CB}\x{82CC}\x{82CD}\x{82CE}\x{82CF}\x{82D0}\x{82D1}' - . '\x{82D2}\x{82D3}\x{82D4}\x{82D5}\x{82D6}\x{82D7}\x{82D8}\x{82D9}\x{82DA}' - . '\x{82DB}\x{82DC}\x{82DD}\x{82DE}\x{82DF}\x{82E0}\x{82E1}\x{82E3}\x{82E4}' - . '\x{82E5}\x{82E6}\x{82E7}\x{82E8}\x{82E9}\x{82EA}\x{82EB}\x{82EC}\x{82ED}' - . '\x{82EE}\x{82EF}\x{82F0}\x{82F1}\x{82F2}\x{82F3}\x{82F4}\x{82F5}\x{82F6}' - . '\x{82F7}\x{82F8}\x{82F9}\x{82FA}\x{82FB}\x{82FD}\x{82FE}\x{82FF}\x{8300}' - . '\x{8301}\x{8302}\x{8303}\x{8304}\x{8305}\x{8306}\x{8307}\x{8308}\x{8309}' - . '\x{830B}\x{830C}\x{830D}\x{830E}\x{830F}\x{8311}\x{8312}\x{8313}\x{8314}' - . '\x{8315}\x{8316}\x{8317}\x{8318}\x{8319}\x{831A}\x{831B}\x{831C}\x{831D}' - . '\x{831E}\x{831F}\x{8320}\x{8321}\x{8322}\x{8323}\x{8324}\x{8325}\x{8326}' - . '\x{8327}\x{8328}\x{8329}\x{832A}\x{832B}\x{832C}\x{832D}\x{832E}\x{832F}' - . '\x{8331}\x{8332}\x{8333}\x{8334}\x{8335}\x{8336}\x{8337}\x{8338}\x{8339}' - . '\x{833A}\x{833B}\x{833C}\x{833D}\x{833E}\x{833F}\x{8340}\x{8341}\x{8342}' - . '\x{8343}\x{8344}\x{8345}\x{8346}\x{8347}\x{8348}\x{8349}\x{834A}\x{834B}' - . '\x{834C}\x{834D}\x{834E}\x{834F}\x{8350}\x{8351}\x{8352}\x{8353}\x{8354}' - . '\x{8356}\x{8357}\x{8358}\x{8359}\x{835A}\x{835B}\x{835C}\x{835D}\x{835E}' - . '\x{835F}\x{8360}\x{8361}\x{8362}\x{8363}\x{8364}\x{8365}\x{8366}\x{8367}' - . '\x{8368}\x{8369}\x{836A}\x{836B}\x{836C}\x{836D}\x{836E}\x{836F}\x{8370}' - . '\x{8371}\x{8372}\x{8373}\x{8374}\x{8375}\x{8376}\x{8377}\x{8378}\x{8379}' - . '\x{837A}\x{837B}\x{837C}\x{837D}\x{837E}\x{837F}\x{8380}\x{8381}\x{8382}' - . '\x{8383}\x{8384}\x{8385}\x{8386}\x{8387}\x{8388}\x{8389}\x{838A}\x{838B}' - . '\x{838C}\x{838D}\x{838E}\x{838F}\x{8390}\x{8391}\x{8392}\x{8393}\x{8394}' - . '\x{8395}\x{8396}\x{8397}\x{8398}\x{8399}\x{839A}\x{839B}\x{839C}\x{839D}' - . '\x{839E}\x{83A0}\x{83A1}\x{83A2}\x{83A3}\x{83A4}\x{83A5}\x{83A6}\x{83A7}' - . '\x{83A8}\x{83A9}\x{83AA}\x{83AB}\x{83AC}\x{83AD}\x{83AE}\x{83AF}\x{83B0}' - . '\x{83B1}\x{83B2}\x{83B3}\x{83B4}\x{83B6}\x{83B7}\x{83B8}\x{83B9}\x{83BA}' - . '\x{83BB}\x{83BC}\x{83BD}\x{83BF}\x{83C0}\x{83C1}\x{83C2}\x{83C3}\x{83C4}' - . '\x{83C5}\x{83C6}\x{83C7}\x{83C8}\x{83C9}\x{83CA}\x{83CB}\x{83CC}\x{83CD}' - . '\x{83CE}\x{83CF}\x{83D0}\x{83D1}\x{83D2}\x{83D3}\x{83D4}\x{83D5}\x{83D6}' - . '\x{83D7}\x{83D8}\x{83D9}\x{83DA}\x{83DB}\x{83DC}\x{83DD}\x{83DE}\x{83DF}' - . '\x{83E0}\x{83E1}\x{83E2}\x{83E3}\x{83E4}\x{83E5}\x{83E7}\x{83E8}\x{83E9}' - . '\x{83EA}\x{83EB}\x{83EC}\x{83EE}\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F3}' - . '\x{83F4}\x{83F5}\x{83F6}\x{83F7}\x{83F8}\x{83F9}\x{83FA}\x{83FB}\x{83FC}' - . '\x{83FD}\x{83FE}\x{83FF}\x{8400}\x{8401}\x{8402}\x{8403}\x{8404}\x{8405}' - . '\x{8406}\x{8407}\x{8408}\x{8409}\x{840A}\x{840B}\x{840C}\x{840D}\x{840E}' - . '\x{840F}\x{8410}\x{8411}\x{8412}\x{8413}\x{8415}\x{8418}\x{8419}\x{841A}' - . '\x{841B}\x{841C}\x{841D}\x{841E}\x{8421}\x{8422}\x{8423}\x{8424}\x{8425}' - . '\x{8426}\x{8427}\x{8428}\x{8429}\x{842A}\x{842B}\x{842C}\x{842D}\x{842E}' - . '\x{842F}\x{8430}\x{8431}\x{8432}\x{8433}\x{8434}\x{8435}\x{8436}\x{8437}' - . '\x{8438}\x{8439}\x{843A}\x{843B}\x{843C}\x{843D}\x{843E}\x{843F}\x{8440}' - . '\x{8441}\x{8442}\x{8443}\x{8444}\x{8445}\x{8446}\x{8447}\x{8448}\x{8449}' - . '\x{844A}\x{844B}\x{844C}\x{844D}\x{844E}\x{844F}\x{8450}\x{8451}\x{8452}' - . '\x{8453}\x{8454}\x{8455}\x{8456}\x{8457}\x{8459}\x{845A}\x{845B}\x{845C}' - . '\x{845D}\x{845E}\x{845F}\x{8460}\x{8461}\x{8462}\x{8463}\x{8464}\x{8465}' - . '\x{8466}\x{8467}\x{8468}\x{8469}\x{846A}\x{846B}\x{846C}\x{846D}\x{846E}' - . '\x{846F}\x{8470}\x{8471}\x{8472}\x{8473}\x{8474}\x{8475}\x{8476}\x{8477}' - . '\x{8478}\x{8479}\x{847A}\x{847B}\x{847C}\x{847D}\x{847E}\x{847F}\x{8480}' - . '\x{8481}\x{8482}\x{8484}\x{8485}\x{8486}\x{8487}\x{8488}\x{8489}\x{848A}' - . '\x{848B}\x{848C}\x{848D}\x{848E}\x{848F}\x{8490}\x{8491}\x{8492}\x{8493}' - . '\x{8494}\x{8496}\x{8497}\x{8498}\x{8499}\x{849A}\x{849B}\x{849C}\x{849D}' - . '\x{849E}\x{849F}\x{84A0}\x{84A1}\x{84A2}\x{84A3}\x{84A4}\x{84A5}\x{84A6}' - . '\x{84A7}\x{84A8}\x{84A9}\x{84AA}\x{84AB}\x{84AC}\x{84AE}\x{84AF}\x{84B0}' - . '\x{84B1}\x{84B2}\x{84B3}\x{84B4}\x{84B5}\x{84B6}\x{84B8}\x{84B9}\x{84BA}' - . '\x{84BB}\x{84BC}\x{84BD}\x{84BE}\x{84BF}\x{84C0}\x{84C1}\x{84C2}\x{84C4}' - . '\x{84C5}\x{84C6}\x{84C7}\x{84C8}\x{84C9}\x{84CA}\x{84CB}\x{84CC}\x{84CD}' - . '\x{84CE}\x{84CF}\x{84D0}\x{84D1}\x{84D2}\x{84D3}\x{84D4}\x{84D5}\x{84D6}' - . '\x{84D7}\x{84D8}\x{84D9}\x{84DB}\x{84DC}\x{84DD}\x{84DE}\x{84DF}\x{84E0}' - . '\x{84E1}\x{84E2}\x{84E3}\x{84E4}\x{84E5}\x{84E6}\x{84E7}\x{84E8}\x{84E9}' - . '\x{84EA}\x{84EB}\x{84EC}\x{84EE}\x{84EF}\x{84F0}\x{84F1}\x{84F2}\x{84F3}' - . '\x{84F4}\x{84F5}\x{84F6}\x{84F7}\x{84F8}\x{84F9}\x{84FA}\x{84FB}\x{84FC}' - . '\x{84FD}\x{84FE}\x{84FF}\x{8500}\x{8501}\x{8502}\x{8503}\x{8504}\x{8506}' - . '\x{8507}\x{8508}\x{8509}\x{850A}\x{850B}\x{850C}\x{850D}\x{850E}\x{850F}' - . '\x{8511}\x{8512}\x{8513}\x{8514}\x{8515}\x{8516}\x{8517}\x{8518}\x{8519}' - . '\x{851A}\x{851B}\x{851C}\x{851D}\x{851E}\x{851F}\x{8520}\x{8521}\x{8522}' - . '\x{8523}\x{8524}\x{8525}\x{8526}\x{8527}\x{8528}\x{8529}\x{852A}\x{852B}' - . '\x{852C}\x{852D}\x{852E}\x{852F}\x{8530}\x{8531}\x{8534}\x{8535}\x{8536}' - . '\x{8537}\x{8538}\x{8539}\x{853A}\x{853B}\x{853C}\x{853D}\x{853E}\x{853F}' - . '\x{8540}\x{8541}\x{8542}\x{8543}\x{8544}\x{8545}\x{8546}\x{8547}\x{8548}' - . '\x{8549}\x{854A}\x{854B}\x{854D}\x{854E}\x{854F}\x{8551}\x{8552}\x{8553}' - . '\x{8554}\x{8555}\x{8556}\x{8557}\x{8558}\x{8559}\x{855A}\x{855B}\x{855C}' - . '\x{855D}\x{855E}\x{855F}\x{8560}\x{8561}\x{8562}\x{8563}\x{8564}\x{8565}' - . '\x{8566}\x{8567}\x{8568}\x{8569}\x{856A}\x{856B}\x{856C}\x{856D}\x{856E}' - . '\x{856F}\x{8570}\x{8571}\x{8572}\x{8573}\x{8574}\x{8575}\x{8576}\x{8577}' - . '\x{8578}\x{8579}\x{857A}\x{857B}\x{857C}\x{857D}\x{857E}\x{8580}\x{8581}' - . '\x{8582}\x{8583}\x{8584}\x{8585}\x{8586}\x{8587}\x{8588}\x{8589}\x{858A}' - . '\x{858B}\x{858C}\x{858D}\x{858E}\x{858F}\x{8590}\x{8591}\x{8592}\x{8594}' - . '\x{8595}\x{8596}\x{8598}\x{8599}\x{859A}\x{859B}\x{859C}\x{859D}\x{859E}' - . '\x{859F}\x{85A0}\x{85A1}\x{85A2}\x{85A3}\x{85A4}\x{85A5}\x{85A6}\x{85A7}' - . '\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AD}\x{85AE}\x{85AF}\x{85B0}' - . '\x{85B1}\x{85B3}\x{85B4}\x{85B5}\x{85B6}\x{85B7}\x{85B8}\x{85B9}\x{85BA}' - . '\x{85BC}\x{85BD}\x{85BE}\x{85BF}\x{85C0}\x{85C1}\x{85C2}\x{85C3}\x{85C4}' - . '\x{85C5}\x{85C6}\x{85C7}\x{85C8}\x{85C9}\x{85CA}\x{85CB}\x{85CD}\x{85CE}' - . '\x{85CF}\x{85D0}\x{85D1}\x{85D2}\x{85D3}\x{85D4}\x{85D5}\x{85D6}\x{85D7}' - . '\x{85D8}\x{85D9}\x{85DA}\x{85DB}\x{85DC}\x{85DD}\x{85DE}\x{85DF}\x{85E0}' - . '\x{85E1}\x{85E2}\x{85E3}\x{85E4}\x{85E5}\x{85E6}\x{85E7}\x{85E8}\x{85E9}' - . '\x{85EA}\x{85EB}\x{85EC}\x{85ED}\x{85EF}\x{85F0}\x{85F1}\x{85F2}\x{85F4}' - . '\x{85F5}\x{85F6}\x{85F7}\x{85F8}\x{85F9}\x{85FA}\x{85FB}\x{85FD}\x{85FE}' - . '\x{85FF}\x{8600}\x{8601}\x{8602}\x{8604}\x{8605}\x{8606}\x{8607}\x{8608}' - . '\x{8609}\x{860A}\x{860B}\x{860C}\x{860F}\x{8611}\x{8612}\x{8613}\x{8614}' - . '\x{8616}\x{8617}\x{8618}\x{8619}\x{861A}\x{861B}\x{861C}\x{861E}\x{861F}' - . '\x{8620}\x{8621}\x{8622}\x{8623}\x{8624}\x{8625}\x{8626}\x{8627}\x{8628}' - . '\x{8629}\x{862A}\x{862B}\x{862C}\x{862D}\x{862E}\x{862F}\x{8630}\x{8631}' - . '\x{8632}\x{8633}\x{8634}\x{8635}\x{8636}\x{8638}\x{8639}\x{863A}\x{863B}' - . '\x{863C}\x{863D}\x{863E}\x{863F}\x{8640}\x{8641}\x{8642}\x{8643}\x{8644}' - . '\x{8645}\x{8646}\x{8647}\x{8648}\x{8649}\x{864A}\x{864B}\x{864C}\x{864D}' - . '\x{864E}\x{864F}\x{8650}\x{8651}\x{8652}\x{8653}\x{8654}\x{8655}\x{8656}' - . '\x{8658}\x{8659}\x{865A}\x{865B}\x{865C}\x{865D}\x{865E}\x{865F}\x{8660}' - . '\x{8661}\x{8662}\x{8663}\x{8664}\x{8665}\x{8666}\x{8667}\x{8668}\x{8669}' - . '\x{866A}\x{866B}\x{866C}\x{866D}\x{866E}\x{866F}\x{8670}\x{8671}\x{8672}' - . '\x{8673}\x{8674}\x{8676}\x{8677}\x{8678}\x{8679}\x{867A}\x{867B}\x{867C}' - . '\x{867D}\x{867E}\x{867F}\x{8680}\x{8681}\x{8682}\x{8683}\x{8684}\x{8685}' - . '\x{8686}\x{8687}\x{8688}\x{868A}\x{868B}\x{868C}\x{868D}\x{868E}\x{868F}' - . '\x{8690}\x{8691}\x{8693}\x{8694}\x{8695}\x{8696}\x{8697}\x{8698}\x{8699}' - . '\x{869A}\x{869B}\x{869C}\x{869D}\x{869E}\x{869F}\x{86A1}\x{86A2}\x{86A3}' - . '\x{86A4}\x{86A5}\x{86A7}\x{86A8}\x{86A9}\x{86AA}\x{86AB}\x{86AC}\x{86AD}' - . '\x{86AE}\x{86AF}\x{86B0}\x{86B1}\x{86B2}\x{86B3}\x{86B4}\x{86B5}\x{86B6}' - . '\x{86B7}\x{86B8}\x{86B9}\x{86BA}\x{86BB}\x{86BC}\x{86BD}\x{86BE}\x{86BF}' - . '\x{86C0}\x{86C1}\x{86C2}\x{86C3}\x{86C4}\x{86C5}\x{86C6}\x{86C7}\x{86C8}' - . '\x{86C9}\x{86CA}\x{86CB}\x{86CC}\x{86CE}\x{86CF}\x{86D0}\x{86D1}\x{86D2}' - . '\x{86D3}\x{86D4}\x{86D6}\x{86D7}\x{86D8}\x{86D9}\x{86DA}\x{86DB}\x{86DC}' - . '\x{86DD}\x{86DE}\x{86DF}\x{86E1}\x{86E2}\x{86E3}\x{86E4}\x{86E5}\x{86E6}' - . '\x{86E8}\x{86E9}\x{86EA}\x{86EB}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F0}' - . '\x{86F1}\x{86F2}\x{86F3}\x{86F4}\x{86F5}\x{86F6}\x{86F7}\x{86F8}\x{86F9}' - . '\x{86FA}\x{86FB}\x{86FC}\x{86FE}\x{86FF}\x{8700}\x{8701}\x{8702}\x{8703}' - . '\x{8704}\x{8705}\x{8706}\x{8707}\x{8708}\x{8709}\x{870A}\x{870B}\x{870C}' - . '\x{870D}\x{870E}\x{870F}\x{8710}\x{8711}\x{8712}\x{8713}\x{8714}\x{8715}' - . '\x{8716}\x{8717}\x{8718}\x{8719}\x{871A}\x{871B}\x{871C}\x{871E}\x{871F}' - . '\x{8720}\x{8721}\x{8722}\x{8723}\x{8724}\x{8725}\x{8726}\x{8727}\x{8728}' - . '\x{8729}\x{872A}\x{872B}\x{872C}\x{872D}\x{872E}\x{8730}\x{8731}\x{8732}' - . '\x{8733}\x{8734}\x{8735}\x{8736}\x{8737}\x{8738}\x{8739}\x{873A}\x{873B}' - . '\x{873C}\x{873E}\x{873F}\x{8740}\x{8741}\x{8742}\x{8743}\x{8744}\x{8746}' - . '\x{8747}\x{8748}\x{8749}\x{874A}\x{874C}\x{874D}\x{874E}\x{874F}\x{8750}' - . '\x{8751}\x{8752}\x{8753}\x{8754}\x{8755}\x{8756}\x{8757}\x{8758}\x{8759}' - . '\x{875A}\x{875B}\x{875C}\x{875D}\x{875E}\x{875F}\x{8760}\x{8761}\x{8762}' - . '\x{8763}\x{8764}\x{8765}\x{8766}\x{8767}\x{8768}\x{8769}\x{876A}\x{876B}' - . '\x{876C}\x{876D}\x{876E}\x{876F}\x{8770}\x{8772}\x{8773}\x{8774}\x{8775}' - . '\x{8776}\x{8777}\x{8778}\x{8779}\x{877A}\x{877B}\x{877C}\x{877D}\x{877E}' - . '\x{8780}\x{8781}\x{8782}\x{8783}\x{8784}\x{8785}\x{8786}\x{8787}\x{8788}' - . '\x{8789}\x{878A}\x{878B}\x{878C}\x{878D}\x{878F}\x{8790}\x{8791}\x{8792}' - . '\x{8793}\x{8794}\x{8795}\x{8796}\x{8797}\x{8798}\x{879A}\x{879B}\x{879C}' - . '\x{879D}\x{879E}\x{879F}\x{87A0}\x{87A1}\x{87A2}\x{87A3}\x{87A4}\x{87A5}' - . '\x{87A6}\x{87A7}\x{87A8}\x{87A9}\x{87AA}\x{87AB}\x{87AC}\x{87AD}\x{87AE}' - . '\x{87AF}\x{87B0}\x{87B1}\x{87B2}\x{87B3}\x{87B4}\x{87B5}\x{87B6}\x{87B7}' - . '\x{87B8}\x{87B9}\x{87BA}\x{87BB}\x{87BC}\x{87BD}\x{87BE}\x{87BF}\x{87C0}' - . '\x{87C1}\x{87C2}\x{87C3}\x{87C4}\x{87C5}\x{87C6}\x{87C7}\x{87C8}\x{87C9}' - . '\x{87CA}\x{87CB}\x{87CC}\x{87CD}\x{87CE}\x{87CF}\x{87D0}\x{87D1}\x{87D2}' - . '\x{87D3}\x{87D4}\x{87D5}\x{87D6}\x{87D7}\x{87D8}\x{87D9}\x{87DB}\x{87DC}' - . '\x{87DD}\x{87DE}\x{87DF}\x{87E0}\x{87E1}\x{87E2}\x{87E3}\x{87E4}\x{87E5}' - . '\x{87E6}\x{87E7}\x{87E8}\x{87E9}\x{87EA}\x{87EB}\x{87EC}\x{87ED}\x{87EE}' - . '\x{87EF}\x{87F1}\x{87F2}\x{87F3}\x{87F4}\x{87F5}\x{87F6}\x{87F7}\x{87F8}' - . '\x{87F9}\x{87FA}\x{87FB}\x{87FC}\x{87FD}\x{87FE}\x{87FF}\x{8800}\x{8801}' - . '\x{8802}\x{8803}\x{8804}\x{8805}\x{8806}\x{8808}\x{8809}\x{880A}\x{880B}' - . '\x{880C}\x{880D}\x{880E}\x{880F}\x{8810}\x{8811}\x{8813}\x{8814}\x{8815}' - . '\x{8816}\x{8817}\x{8818}\x{8819}\x{881A}\x{881B}\x{881C}\x{881D}\x{881E}' - . '\x{881F}\x{8820}\x{8821}\x{8822}\x{8823}\x{8824}\x{8825}\x{8826}\x{8827}' - . '\x{8828}\x{8829}\x{882A}\x{882B}\x{882C}\x{882E}\x{882F}\x{8830}\x{8831}' - . '\x{8832}\x{8833}\x{8834}\x{8835}\x{8836}\x{8837}\x{8838}\x{8839}\x{883B}' - . '\x{883C}\x{883D}\x{883E}\x{883F}\x{8840}\x{8841}\x{8842}\x{8843}\x{8844}' - . '\x{8845}\x{8846}\x{8848}\x{8849}\x{884A}\x{884B}\x{884C}\x{884D}\x{884E}' - . '\x{884F}\x{8850}\x{8851}\x{8852}\x{8853}\x{8854}\x{8855}\x{8856}\x{8857}' - . '\x{8859}\x{885A}\x{885B}\x{885D}\x{885E}\x{8860}\x{8861}\x{8862}\x{8863}' - . '\x{8864}\x{8865}\x{8866}\x{8867}\x{8868}\x{8869}\x{886A}\x{886B}\x{886C}' - . '\x{886D}\x{886E}\x{886F}\x{8870}\x{8871}\x{8872}\x{8873}\x{8874}\x{8875}' - . '\x{8876}\x{8877}\x{8878}\x{8879}\x{887B}\x{887C}\x{887D}\x{887E}\x{887F}' - . '\x{8880}\x{8881}\x{8882}\x{8883}\x{8884}\x{8885}\x{8886}\x{8887}\x{8888}' - . '\x{8889}\x{888A}\x{888B}\x{888C}\x{888D}\x{888E}\x{888F}\x{8890}\x{8891}' - . '\x{8892}\x{8893}\x{8894}\x{8895}\x{8896}\x{8897}\x{8898}\x{8899}\x{889A}' - . '\x{889B}\x{889C}\x{889D}\x{889E}\x{889F}\x{88A0}\x{88A1}\x{88A2}\x{88A3}' - . '\x{88A4}\x{88A5}\x{88A6}\x{88A7}\x{88A8}\x{88A9}\x{88AA}\x{88AB}\x{88AC}' - . '\x{88AD}\x{88AE}\x{88AF}\x{88B0}\x{88B1}\x{88B2}\x{88B3}\x{88B4}\x{88B6}' - . '\x{88B7}\x{88B8}\x{88B9}\x{88BA}\x{88BB}\x{88BC}\x{88BD}\x{88BE}\x{88BF}' - . '\x{88C0}\x{88C1}\x{88C2}\x{88C3}\x{88C4}\x{88C5}\x{88C6}\x{88C7}\x{88C8}' - . '\x{88C9}\x{88CA}\x{88CB}\x{88CC}\x{88CD}\x{88CE}\x{88CF}\x{88D0}\x{88D1}' - . '\x{88D2}\x{88D3}\x{88D4}\x{88D5}\x{88D6}\x{88D7}\x{88D8}\x{88D9}\x{88DA}' - . '\x{88DB}\x{88DC}\x{88DD}\x{88DE}\x{88DF}\x{88E0}\x{88E1}\x{88E2}\x{88E3}' - . '\x{88E4}\x{88E5}\x{88E7}\x{88E8}\x{88EA}\x{88EB}\x{88EC}\x{88EE}\x{88EF}' - . '\x{88F0}\x{88F1}\x{88F2}\x{88F3}\x{88F4}\x{88F5}\x{88F6}\x{88F7}\x{88F8}' - . '\x{88F9}\x{88FA}\x{88FB}\x{88FC}\x{88FD}\x{88FE}\x{88FF}\x{8900}\x{8901}' - . '\x{8902}\x{8904}\x{8905}\x{8906}\x{8907}\x{8908}\x{8909}\x{890A}\x{890B}' - . '\x{890C}\x{890D}\x{890E}\x{8910}\x{8911}\x{8912}\x{8913}\x{8914}\x{8915}' - . '\x{8916}\x{8917}\x{8918}\x{8919}\x{891A}\x{891B}\x{891C}\x{891D}\x{891E}' - . '\x{891F}\x{8920}\x{8921}\x{8922}\x{8923}\x{8925}\x{8926}\x{8927}\x{8928}' - . '\x{8929}\x{892A}\x{892B}\x{892C}\x{892D}\x{892E}\x{892F}\x{8930}\x{8931}' - . '\x{8932}\x{8933}\x{8934}\x{8935}\x{8936}\x{8937}\x{8938}\x{8939}\x{893A}' - . '\x{893B}\x{893C}\x{893D}\x{893E}\x{893F}\x{8940}\x{8941}\x{8942}\x{8943}' - . '\x{8944}\x{8945}\x{8946}\x{8947}\x{8948}\x{8949}\x{894A}\x{894B}\x{894C}' - . '\x{894E}\x{894F}\x{8950}\x{8951}\x{8952}\x{8953}\x{8954}\x{8955}\x{8956}' - . '\x{8957}\x{8958}\x{8959}\x{895A}\x{895B}\x{895C}\x{895D}\x{895E}\x{895F}' - . '\x{8960}\x{8961}\x{8962}\x{8963}\x{8964}\x{8966}\x{8967}\x{8968}\x{8969}' - . '\x{896A}\x{896B}\x{896C}\x{896D}\x{896E}\x{896F}\x{8970}\x{8971}\x{8972}' - . '\x{8973}\x{8974}\x{8976}\x{8977}\x{8978}\x{8979}\x{897A}\x{897B}\x{897C}' - . '\x{897E}\x{897F}\x{8980}\x{8981}\x{8982}\x{8983}\x{8984}\x{8985}\x{8986}' - . '\x{8987}\x{8988}\x{8989}\x{898A}\x{898B}\x{898C}\x{898E}\x{898F}\x{8991}' - . '\x{8992}\x{8993}\x{8995}\x{8996}\x{8997}\x{8998}\x{899A}\x{899B}\x{899C}' - . '\x{899D}\x{899E}\x{899F}\x{89A0}\x{89A1}\x{89A2}\x{89A3}\x{89A4}\x{89A5}' - . '\x{89A6}\x{89A7}\x{89A8}\x{89AA}\x{89AB}\x{89AC}\x{89AD}\x{89AE}\x{89AF}' - . '\x{89B1}\x{89B2}\x{89B3}\x{89B5}\x{89B6}\x{89B7}\x{89B8}\x{89B9}\x{89BA}' - . '\x{89BD}\x{89BE}\x{89BF}\x{89C0}\x{89C1}\x{89C2}\x{89C3}\x{89C4}\x{89C5}' - . '\x{89C6}\x{89C7}\x{89C8}\x{89C9}\x{89CA}\x{89CB}\x{89CC}\x{89CD}\x{89CE}' - . '\x{89CF}\x{89D0}\x{89D1}\x{89D2}\x{89D3}\x{89D4}\x{89D5}\x{89D6}\x{89D7}' - . '\x{89D8}\x{89D9}\x{89DA}\x{89DB}\x{89DC}\x{89DD}\x{89DE}\x{89DF}\x{89E0}' - . '\x{89E1}\x{89E2}\x{89E3}\x{89E4}\x{89E5}\x{89E6}\x{89E7}\x{89E8}\x{89E9}' - . '\x{89EA}\x{89EB}\x{89EC}\x{89ED}\x{89EF}\x{89F0}\x{89F1}\x{89F2}\x{89F3}' - . '\x{89F4}\x{89F6}\x{89F7}\x{89F8}\x{89FA}\x{89FB}\x{89FC}\x{89FE}\x{89FF}' - . '\x{8A00}\x{8A01}\x{8A02}\x{8A03}\x{8A04}\x{8A07}\x{8A08}\x{8A09}\x{8A0A}' - . '\x{8A0B}\x{8A0C}\x{8A0D}\x{8A0E}\x{8A0F}\x{8A10}\x{8A11}\x{8A12}\x{8A13}' - . '\x{8A15}\x{8A16}\x{8A17}\x{8A18}\x{8A1A}\x{8A1B}\x{8A1C}\x{8A1D}\x{8A1E}' - . '\x{8A1F}\x{8A22}\x{8A23}\x{8A24}\x{8A25}\x{8A26}\x{8A27}\x{8A28}\x{8A29}' - . '\x{8A2A}\x{8A2C}\x{8A2D}\x{8A2E}\x{8A2F}\x{8A30}\x{8A31}\x{8A32}\x{8A34}' - . '\x{8A35}\x{8A36}\x{8A37}\x{8A38}\x{8A39}\x{8A3A}\x{8A3B}\x{8A3C}\x{8A3E}' - . '\x{8A3F}\x{8A40}\x{8A41}\x{8A42}\x{8A43}\x{8A44}\x{8A45}\x{8A46}\x{8A47}' - . '\x{8A48}\x{8A49}\x{8A4A}\x{8A4C}\x{8A4D}\x{8A4E}\x{8A4F}\x{8A50}\x{8A51}' - . '\x{8A52}\x{8A53}\x{8A54}\x{8A55}\x{8A56}\x{8A57}\x{8A58}\x{8A59}\x{8A5A}' - . '\x{8A5B}\x{8A5C}\x{8A5D}\x{8A5E}\x{8A5F}\x{8A60}\x{8A61}\x{8A62}\x{8A63}' - . '\x{8A65}\x{8A66}\x{8A67}\x{8A68}\x{8A69}\x{8A6A}\x{8A6B}\x{8A6C}\x{8A6D}' - . '\x{8A6E}\x{8A6F}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A74}\x{8A75}\x{8A76}' - . '\x{8A77}\x{8A79}\x{8A7A}\x{8A7B}\x{8A7C}\x{8A7E}\x{8A7F}\x{8A80}\x{8A81}' - . '\x{8A82}\x{8A83}\x{8A84}\x{8A85}\x{8A86}\x{8A87}\x{8A89}\x{8A8A}\x{8A8B}' - . '\x{8A8C}\x{8A8D}\x{8A8E}\x{8A8F}\x{8A90}\x{8A91}\x{8A92}\x{8A93}\x{8A94}' - . '\x{8A95}\x{8A96}\x{8A97}\x{8A98}\x{8A99}\x{8A9A}\x{8A9B}\x{8A9C}\x{8A9D}' - . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA2}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA7}' - . '\x{8AA8}\x{8AA9}\x{8AAA}\x{8AAB}\x{8AAC}\x{8AAE}\x{8AB0}\x{8AB1}\x{8AB2}' - . '\x{8AB3}\x{8AB4}\x{8AB5}\x{8AB6}\x{8AB8}\x{8AB9}\x{8ABA}\x{8ABB}\x{8ABC}' - . '\x{8ABD}\x{8ABE}\x{8ABF}\x{8AC0}\x{8AC1}\x{8AC2}\x{8AC3}\x{8AC4}\x{8AC5}' - . '\x{8AC6}\x{8AC7}\x{8AC8}\x{8AC9}\x{8ACA}\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACE}' - . '\x{8ACF}\x{8AD1}\x{8AD2}\x{8AD3}\x{8AD4}\x{8AD5}\x{8AD6}\x{8AD7}\x{8AD8}' - . '\x{8AD9}\x{8ADA}\x{8ADB}\x{8ADC}\x{8ADD}\x{8ADE}\x{8ADF}\x{8AE0}\x{8AE1}' - . '\x{8AE2}\x{8AE3}\x{8AE4}\x{8AE5}\x{8AE6}\x{8AE7}\x{8AE8}\x{8AE9}\x{8AEA}' - . '\x{8AEB}\x{8AED}\x{8AEE}\x{8AEF}\x{8AF0}\x{8AF1}\x{8AF2}\x{8AF3}\x{8AF4}' - . '\x{8AF5}\x{8AF6}\x{8AF7}\x{8AF8}\x{8AF9}\x{8AFA}\x{8AFB}\x{8AFC}\x{8AFD}' - . '\x{8AFE}\x{8AFF}\x{8B00}\x{8B01}\x{8B02}\x{8B03}\x{8B04}\x{8B05}\x{8B06}' - . '\x{8B07}\x{8B08}\x{8B09}\x{8B0A}\x{8B0B}\x{8B0D}\x{8B0E}\x{8B0F}\x{8B10}' - . '\x{8B11}\x{8B12}\x{8B13}\x{8B14}\x{8B15}\x{8B16}\x{8B17}\x{8B18}\x{8B19}' - . '\x{8B1A}\x{8B1B}\x{8B1C}\x{8B1D}\x{8B1E}\x{8B1F}\x{8B20}\x{8B21}\x{8B22}' - . '\x{8B23}\x{8B24}\x{8B25}\x{8B26}\x{8B27}\x{8B28}\x{8B2A}\x{8B2B}\x{8B2C}' - . '\x{8B2D}\x{8B2E}\x{8B2F}\x{8B30}\x{8B31}\x{8B33}\x{8B34}\x{8B35}\x{8B36}' - . '\x{8B37}\x{8B39}\x{8B3A}\x{8B3B}\x{8B3C}\x{8B3D}\x{8B3E}\x{8B40}\x{8B41}' - . '\x{8B42}\x{8B43}\x{8B44}\x{8B45}\x{8B46}\x{8B47}\x{8B48}\x{8B49}\x{8B4A}' - . '\x{8B4B}\x{8B4C}\x{8B4D}\x{8B4E}\x{8B4F}\x{8B50}\x{8B51}\x{8B52}\x{8B53}' - . '\x{8B54}\x{8B55}\x{8B56}\x{8B57}\x{8B58}\x{8B59}\x{8B5A}\x{8B5B}\x{8B5C}' - . '\x{8B5D}\x{8B5E}\x{8B5F}\x{8B60}\x{8B63}\x{8B64}\x{8B65}\x{8B66}\x{8B67}' - . '\x{8B68}\x{8B6A}\x{8B6B}\x{8B6C}\x{8B6D}\x{8B6E}\x{8B6F}\x{8B70}\x{8B71}' - . '\x{8B73}\x{8B74}\x{8B76}\x{8B77}\x{8B78}\x{8B79}\x{8B7A}\x{8B7B}\x{8B7D}' - . '\x{8B7E}\x{8B7F}\x{8B80}\x{8B82}\x{8B83}\x{8B84}\x{8B85}\x{8B86}\x{8B88}' - . '\x{8B89}\x{8B8A}\x{8B8B}\x{8B8C}\x{8B8E}\x{8B90}\x{8B91}\x{8B92}\x{8B93}' - . '\x{8B94}\x{8B95}\x{8B96}\x{8B97}\x{8B98}\x{8B99}\x{8B9A}\x{8B9C}\x{8B9D}' - . '\x{8B9E}\x{8B9F}\x{8BA0}\x{8BA1}\x{8BA2}\x{8BA3}\x{8BA4}\x{8BA5}\x{8BA6}' - . '\x{8BA7}\x{8BA8}\x{8BA9}\x{8BAA}\x{8BAB}\x{8BAC}\x{8BAD}\x{8BAE}\x{8BAF}' - . '\x{8BB0}\x{8BB1}\x{8BB2}\x{8BB3}\x{8BB4}\x{8BB5}\x{8BB6}\x{8BB7}\x{8BB8}' - . '\x{8BB9}\x{8BBA}\x{8BBB}\x{8BBC}\x{8BBD}\x{8BBE}\x{8BBF}\x{8BC0}\x{8BC1}' - . '\x{8BC2}\x{8BC3}\x{8BC4}\x{8BC5}\x{8BC6}\x{8BC7}\x{8BC8}\x{8BC9}\x{8BCA}' - . '\x{8BCB}\x{8BCC}\x{8BCD}\x{8BCE}\x{8BCF}\x{8BD0}\x{8BD1}\x{8BD2}\x{8BD3}' - . '\x{8BD4}\x{8BD5}\x{8BD6}\x{8BD7}\x{8BD8}\x{8BD9}\x{8BDA}\x{8BDB}\x{8BDC}' - . '\x{8BDD}\x{8BDE}\x{8BDF}\x{8BE0}\x{8BE1}\x{8BE2}\x{8BE3}\x{8BE4}\x{8BE5}' - . '\x{8BE6}\x{8BE7}\x{8BE8}\x{8BE9}\x{8BEA}\x{8BEB}\x{8BEC}\x{8BED}\x{8BEE}' - . '\x{8BEF}\x{8BF0}\x{8BF1}\x{8BF2}\x{8BF3}\x{8BF4}\x{8BF5}\x{8BF6}\x{8BF7}' - . '\x{8BF8}\x{8BF9}\x{8BFA}\x{8BFB}\x{8BFC}\x{8BFD}\x{8BFE}\x{8BFF}\x{8C00}' - . '\x{8C01}\x{8C02}\x{8C03}\x{8C04}\x{8C05}\x{8C06}\x{8C07}\x{8C08}\x{8C09}' - . '\x{8C0A}\x{8C0B}\x{8C0C}\x{8C0D}\x{8C0E}\x{8C0F}\x{8C10}\x{8C11}\x{8C12}' - . '\x{8C13}\x{8C14}\x{8C15}\x{8C16}\x{8C17}\x{8C18}\x{8C19}\x{8C1A}\x{8C1B}' - . '\x{8C1C}\x{8C1D}\x{8C1E}\x{8C1F}\x{8C20}\x{8C21}\x{8C22}\x{8C23}\x{8C24}' - . '\x{8C25}\x{8C26}\x{8C27}\x{8C28}\x{8C29}\x{8C2A}\x{8C2B}\x{8C2C}\x{8C2D}' - . '\x{8C2E}\x{8C2F}\x{8C30}\x{8C31}\x{8C32}\x{8C33}\x{8C34}\x{8C35}\x{8C36}' - . '\x{8C37}\x{8C39}\x{8C3A}\x{8C3B}\x{8C3C}\x{8C3D}\x{8C3E}\x{8C3F}\x{8C41}' - . '\x{8C42}\x{8C43}\x{8C45}\x{8C46}\x{8C47}\x{8C48}\x{8C49}\x{8C4A}\x{8C4B}' - . '\x{8C4C}\x{8C4D}\x{8C4E}\x{8C4F}\x{8C50}\x{8C54}\x{8C55}\x{8C56}\x{8C57}' - . '\x{8C59}\x{8C5A}\x{8C5B}\x{8C5C}\x{8C5D}\x{8C5E}\x{8C5F}\x{8C60}\x{8C61}' - . '\x{8C62}\x{8C63}\x{8C64}\x{8C65}\x{8C66}\x{8C67}\x{8C68}\x{8C69}\x{8C6A}' - . '\x{8C6B}\x{8C6C}\x{8C6D}\x{8C6E}\x{8C6F}\x{8C70}\x{8C71}\x{8C72}\x{8C73}' - . '\x{8C75}\x{8C76}\x{8C77}\x{8C78}\x{8C79}\x{8C7A}\x{8C7B}\x{8C7D}\x{8C7E}' - . '\x{8C80}\x{8C81}\x{8C82}\x{8C84}\x{8C85}\x{8C86}\x{8C88}\x{8C89}\x{8C8A}' - . '\x{8C8C}\x{8C8D}\x{8C8F}\x{8C90}\x{8C91}\x{8C92}\x{8C93}\x{8C94}\x{8C95}' - . '\x{8C96}\x{8C97}\x{8C98}\x{8C99}\x{8C9A}\x{8C9C}\x{8C9D}\x{8C9E}\x{8C9F}' - . '\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA3}\x{8CA4}\x{8CA5}\x{8CA7}\x{8CA8}\x{8CA9}' - . '\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}\x{8CB1}\x{8CB2}' - . '\x{8CB3}\x{8CB4}\x{8CB5}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CB9}\x{8CBA}\x{8CBB}' - . '\x{8CBC}\x{8CBD}\x{8CBE}\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}' - . '\x{8CC5}\x{8CC6}\x{8CC7}\x{8CC8}\x{8CC9}\x{8CCA}\x{8CCC}\x{8CCE}\x{8CCF}' - . '\x{8CD0}\x{8CD1}\x{8CD2}\x{8CD3}\x{8CD4}\x{8CD5}\x{8CD7}\x{8CD9}\x{8CDA}' - . '\x{8CDB}\x{8CDC}\x{8CDD}\x{8CDE}\x{8CDF}\x{8CE0}\x{8CE1}\x{8CE2}\x{8CE3}' - . '\x{8CE4}\x{8CE5}\x{8CE6}\x{8CE7}\x{8CE8}\x{8CEA}\x{8CEB}\x{8CEC}\x{8CED}' - . '\x{8CEE}\x{8CEF}\x{8CF0}\x{8CF1}\x{8CF2}\x{8CF3}\x{8CF4}\x{8CF5}\x{8CF6}' - . '\x{8CF8}\x{8CF9}\x{8CFA}\x{8CFB}\x{8CFC}\x{8CFD}\x{8CFE}\x{8CFF}\x{8D00}' - . '\x{8D02}\x{8D03}\x{8D04}\x{8D05}\x{8D06}\x{8D07}\x{8D08}\x{8D09}\x{8D0A}' - . '\x{8D0B}\x{8D0C}\x{8D0D}\x{8D0E}\x{8D0F}\x{8D10}\x{8D13}\x{8D14}\x{8D15}' - . '\x{8D16}\x{8D17}\x{8D18}\x{8D19}\x{8D1A}\x{8D1B}\x{8D1C}\x{8D1D}\x{8D1E}' - . '\x{8D1F}\x{8D20}\x{8D21}\x{8D22}\x{8D23}\x{8D24}\x{8D25}\x{8D26}\x{8D27}' - . '\x{8D28}\x{8D29}\x{8D2A}\x{8D2B}\x{8D2C}\x{8D2D}\x{8D2E}\x{8D2F}\x{8D30}' - . '\x{8D31}\x{8D32}\x{8D33}\x{8D34}\x{8D35}\x{8D36}\x{8D37}\x{8D38}\x{8D39}' - . '\x{8D3A}\x{8D3B}\x{8D3C}\x{8D3D}\x{8D3E}\x{8D3F}\x{8D40}\x{8D41}\x{8D42}' - . '\x{8D43}\x{8D44}\x{8D45}\x{8D46}\x{8D47}\x{8D48}\x{8D49}\x{8D4A}\x{8D4B}' - . '\x{8D4C}\x{8D4D}\x{8D4E}\x{8D4F}\x{8D50}\x{8D51}\x{8D52}\x{8D53}\x{8D54}' - . '\x{8D55}\x{8D56}\x{8D57}\x{8D58}\x{8D59}\x{8D5A}\x{8D5B}\x{8D5C}\x{8D5D}' - . '\x{8D5E}\x{8D5F}\x{8D60}\x{8D61}\x{8D62}\x{8D63}\x{8D64}\x{8D65}\x{8D66}' - . '\x{8D67}\x{8D68}\x{8D69}\x{8D6A}\x{8D6B}\x{8D6C}\x{8D6D}\x{8D6E}\x{8D6F}' - . '\x{8D70}\x{8D71}\x{8D72}\x{8D73}\x{8D74}\x{8D75}\x{8D76}\x{8D77}\x{8D78}' - . '\x{8D79}\x{8D7A}\x{8D7B}\x{8D7D}\x{8D7E}\x{8D7F}\x{8D80}\x{8D81}\x{8D82}' - . '\x{8D83}\x{8D84}\x{8D85}\x{8D86}\x{8D87}\x{8D88}\x{8D89}\x{8D8A}\x{8D8B}' - . '\x{8D8C}\x{8D8D}\x{8D8E}\x{8D8F}\x{8D90}\x{8D91}\x{8D92}\x{8D93}\x{8D94}' - . '\x{8D95}\x{8D96}\x{8D97}\x{8D98}\x{8D99}\x{8D9A}\x{8D9B}\x{8D9C}\x{8D9D}' - . '\x{8D9E}\x{8D9F}\x{8DA0}\x{8DA1}\x{8DA2}\x{8DA3}\x{8DA4}\x{8DA5}\x{8DA7}' - . '\x{8DA8}\x{8DA9}\x{8DAA}\x{8DAB}\x{8DAC}\x{8DAD}\x{8DAE}\x{8DAF}\x{8DB0}' - . '\x{8DB1}\x{8DB2}\x{8DB3}\x{8DB4}\x{8DB5}\x{8DB6}\x{8DB7}\x{8DB8}\x{8DB9}' - . '\x{8DBA}\x{8DBB}\x{8DBC}\x{8DBD}\x{8DBE}\x{8DBF}\x{8DC1}\x{8DC2}\x{8DC3}' - . '\x{8DC4}\x{8DC5}\x{8DC6}\x{8DC7}\x{8DC8}\x{8DC9}\x{8DCA}\x{8DCB}\x{8DCC}' - . '\x{8DCD}\x{8DCE}\x{8DCF}\x{8DD0}\x{8DD1}\x{8DD2}\x{8DD3}\x{8DD4}\x{8DD5}' - . '\x{8DD6}\x{8DD7}\x{8DD8}\x{8DD9}\x{8DDA}\x{8DDB}\x{8DDC}\x{8DDD}\x{8DDE}' - . '\x{8DDF}\x{8DE0}\x{8DE1}\x{8DE2}\x{8DE3}\x{8DE4}\x{8DE6}\x{8DE7}\x{8DE8}' - . '\x{8DE9}\x{8DEA}\x{8DEB}\x{8DEC}\x{8DED}\x{8DEE}\x{8DEF}\x{8DF0}\x{8DF1}' - . '\x{8DF2}\x{8DF3}\x{8DF4}\x{8DF5}\x{8DF6}\x{8DF7}\x{8DF8}\x{8DF9}\x{8DFA}' - . '\x{8DFB}\x{8DFC}\x{8DFD}\x{8DFE}\x{8DFF}\x{8E00}\x{8E02}\x{8E03}\x{8E04}' - . '\x{8E05}\x{8E06}\x{8E07}\x{8E08}\x{8E09}\x{8E0A}\x{8E0C}\x{8E0D}\x{8E0E}' - . '\x{8E0F}\x{8E10}\x{8E11}\x{8E12}\x{8E13}\x{8E14}\x{8E15}\x{8E16}\x{8E17}' - . '\x{8E18}\x{8E19}\x{8E1A}\x{8E1B}\x{8E1C}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E20}' - . '\x{8E21}\x{8E22}\x{8E23}\x{8E24}\x{8E25}\x{8E26}\x{8E27}\x{8E28}\x{8E29}' - . '\x{8E2A}\x{8E2B}\x{8E2C}\x{8E2D}\x{8E2E}\x{8E2F}\x{8E30}\x{8E31}\x{8E33}' - . '\x{8E34}\x{8E35}\x{8E36}\x{8E37}\x{8E38}\x{8E39}\x{8E3A}\x{8E3B}\x{8E3C}' - . '\x{8E3D}\x{8E3E}\x{8E3F}\x{8E40}\x{8E41}\x{8E42}\x{8E43}\x{8E44}\x{8E45}' - . '\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4B}\x{8E4C}\x{8E4D}\x{8E4E}\x{8E50}' - . '\x{8E51}\x{8E52}\x{8E53}\x{8E54}\x{8E55}\x{8E56}\x{8E57}\x{8E58}\x{8E59}' - . '\x{8E5A}\x{8E5B}\x{8E5C}\x{8E5D}\x{8E5E}\x{8E5F}\x{8E60}\x{8E61}\x{8E62}' - . '\x{8E63}\x{8E64}\x{8E65}\x{8E66}\x{8E67}\x{8E68}\x{8E69}\x{8E6A}\x{8E6B}' - . '\x{8E6C}\x{8E6D}\x{8E6F}\x{8E70}\x{8E71}\x{8E72}\x{8E73}\x{8E74}\x{8E76}' - . '\x{8E78}\x{8E7A}\x{8E7B}\x{8E7C}\x{8E7D}\x{8E7E}\x{8E7F}\x{8E80}\x{8E81}' - . '\x{8E82}\x{8E83}\x{8E84}\x{8E85}\x{8E86}\x{8E87}\x{8E88}\x{8E89}\x{8E8A}' - . '\x{8E8B}\x{8E8C}\x{8E8D}\x{8E8E}\x{8E8F}\x{8E90}\x{8E91}\x{8E92}\x{8E93}' - . '\x{8E94}\x{8E95}\x{8E96}\x{8E97}\x{8E98}\x{8E9A}\x{8E9C}\x{8E9D}\x{8E9E}' - . '\x{8E9F}\x{8EA0}\x{8EA1}\x{8EA3}\x{8EA4}\x{8EA5}\x{8EA6}\x{8EA7}\x{8EA8}' - . '\x{8EA9}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAD}\x{8EAE}\x{8EAF}\x{8EB0}\x{8EB1}' - . '\x{8EB2}\x{8EB4}\x{8EB5}\x{8EB8}\x{8EB9}\x{8EBA}\x{8EBB}\x{8EBC}\x{8EBD}' - . '\x{8EBE}\x{8EBF}\x{8EC0}\x{8EC2}\x{8EC3}\x{8EC5}\x{8EC6}\x{8EC7}\x{8EC8}' - . '\x{8EC9}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ECE}\x{8ECF}\x{8ED0}\x{8ED1}' - . '\x{8ED2}\x{8ED3}\x{8ED4}\x{8ED5}\x{8ED6}\x{8ED7}\x{8ED8}\x{8EDA}\x{8EDB}' - . '\x{8EDC}\x{8EDD}\x{8EDE}\x{8EDF}\x{8EE0}\x{8EE1}\x{8EE4}\x{8EE5}\x{8EE6}' - . '\x{8EE7}\x{8EE8}\x{8EE9}\x{8EEA}\x{8EEB}\x{8EEC}\x{8EED}\x{8EEE}\x{8EEF}' - . '\x{8EF1}\x{8EF2}\x{8EF3}\x{8EF4}\x{8EF5}\x{8EF6}\x{8EF7}\x{8EF8}\x{8EF9}' - . '\x{8EFA}\x{8EFB}\x{8EFC}\x{8EFD}\x{8EFE}\x{8EFF}\x{8F00}\x{8F01}\x{8F02}' - . '\x{8F03}\x{8F04}\x{8F05}\x{8F06}\x{8F07}\x{8F08}\x{8F09}\x{8F0A}\x{8F0B}' - . '\x{8F0D}\x{8F0E}\x{8F10}\x{8F11}\x{8F12}\x{8F13}\x{8F14}\x{8F15}\x{8F16}' - . '\x{8F17}\x{8F18}\x{8F1A}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1E}\x{8F1F}\x{8F20}' - . '\x{8F21}\x{8F22}\x{8F23}\x{8F24}\x{8F25}\x{8F26}\x{8F27}\x{8F28}\x{8F29}' - . '\x{8F2A}\x{8F2B}\x{8F2C}\x{8F2E}\x{8F2F}\x{8F30}\x{8F31}\x{8F32}\x{8F33}' - . '\x{8F34}\x{8F35}\x{8F36}\x{8F37}\x{8F38}\x{8F39}\x{8F3B}\x{8F3C}\x{8F3D}' - . '\x{8F3E}\x{8F3F}\x{8F40}\x{8F42}\x{8F43}\x{8F44}\x{8F45}\x{8F46}\x{8F47}' - . '\x{8F48}\x{8F49}\x{8F4A}\x{8F4B}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F4F}\x{8F50}' - . '\x{8F51}\x{8F52}\x{8F53}\x{8F54}\x{8F55}\x{8F56}\x{8F57}\x{8F58}\x{8F59}' - . '\x{8F5A}\x{8F5B}\x{8F5D}\x{8F5E}\x{8F5F}\x{8F60}\x{8F61}\x{8F62}\x{8F63}' - . '\x{8F64}\x{8F65}\x{8F66}\x{8F67}\x{8F68}\x{8F69}\x{8F6A}\x{8F6B}\x{8F6C}' - . '\x{8F6D}\x{8F6E}\x{8F6F}\x{8F70}\x{8F71}\x{8F72}\x{8F73}\x{8F74}\x{8F75}' - . '\x{8F76}\x{8F77}\x{8F78}\x{8F79}\x{8F7A}\x{8F7B}\x{8F7C}\x{8F7D}\x{8F7E}' - . '\x{8F7F}\x{8F80}\x{8F81}\x{8F82}\x{8F83}\x{8F84}\x{8F85}\x{8F86}\x{8F87}' - . '\x{8F88}\x{8F89}\x{8F8A}\x{8F8B}\x{8F8C}\x{8F8D}\x{8F8E}\x{8F8F}\x{8F90}' - . '\x{8F91}\x{8F92}\x{8F93}\x{8F94}\x{8F95}\x{8F96}\x{8F97}\x{8F98}\x{8F99}' - . '\x{8F9A}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA0}\x{8FA1}\x{8FA2}\x{8FA3}' - . '\x{8FA5}\x{8FA6}\x{8FA7}\x{8FA8}\x{8FA9}\x{8FAA}\x{8FAB}\x{8FAC}\x{8FAD}' - . '\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB4}\x{8FB5}\x{8FB6}\x{8FB7}' - . '\x{8FB8}\x{8FB9}\x{8FBB}\x{8FBC}\x{8FBD}\x{8FBE}\x{8FBF}\x{8FC0}\x{8FC1}' - . '\x{8FC2}\x{8FC4}\x{8FC5}\x{8FC6}\x{8FC7}\x{8FC8}\x{8FC9}\x{8FCB}\x{8FCC}' - . '\x{8FCD}\x{8FCE}\x{8FCF}\x{8FD0}\x{8FD1}\x{8FD2}\x{8FD3}\x{8FD4}\x{8FD5}' - . '\x{8FD6}\x{8FD7}\x{8FD8}\x{8FD9}\x{8FDA}\x{8FDB}\x{8FDC}\x{8FDD}\x{8FDE}' - . '\x{8FDF}\x{8FE0}\x{8FE1}\x{8FE2}\x{8FE3}\x{8FE4}\x{8FE5}\x{8FE6}\x{8FE8}' - . '\x{8FE9}\x{8FEA}\x{8FEB}\x{8FEC}\x{8FED}\x{8FEE}\x{8FEF}\x{8FF0}\x{8FF1}' - . '\x{8FF2}\x{8FF3}\x{8FF4}\x{8FF5}\x{8FF6}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}' - . '\x{8FFB}\x{8FFC}\x{8FFD}\x{8FFE}\x{8FFF}\x{9000}\x{9001}\x{9002}\x{9003}' - . '\x{9004}\x{9005}\x{9006}\x{9007}\x{9008}\x{9009}\x{900A}\x{900B}\x{900C}' - . '\x{900D}\x{900F}\x{9010}\x{9011}\x{9012}\x{9013}\x{9014}\x{9015}\x{9016}' - . '\x{9017}\x{9018}\x{9019}\x{901A}\x{901B}\x{901C}\x{901D}\x{901E}\x{901F}' - . '\x{9020}\x{9021}\x{9022}\x{9023}\x{9024}\x{9025}\x{9026}\x{9027}\x{9028}' - . '\x{9029}\x{902B}\x{902D}\x{902E}\x{902F}\x{9030}\x{9031}\x{9032}\x{9033}' - . '\x{9034}\x{9035}\x{9036}\x{9038}\x{903A}\x{903B}\x{903C}\x{903D}\x{903E}' - . '\x{903F}\x{9041}\x{9042}\x{9043}\x{9044}\x{9045}\x{9047}\x{9048}\x{9049}' - . '\x{904A}\x{904B}\x{904C}\x{904D}\x{904E}\x{904F}\x{9050}\x{9051}\x{9052}' - . '\x{9053}\x{9054}\x{9055}\x{9056}\x{9057}\x{9058}\x{9059}\x{905A}\x{905B}' - . '\x{905C}\x{905D}\x{905E}\x{905F}\x{9060}\x{9061}\x{9062}\x{9063}\x{9064}' - . '\x{9065}\x{9066}\x{9067}\x{9068}\x{9069}\x{906A}\x{906B}\x{906C}\x{906D}' - . '\x{906E}\x{906F}\x{9070}\x{9071}\x{9072}\x{9073}\x{9074}\x{9075}\x{9076}' - . '\x{9077}\x{9078}\x{9079}\x{907A}\x{907B}\x{907C}\x{907D}\x{907E}\x{907F}' - . '\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9085}\x{9086}\x{9087}\x{9088}' - . '\x{9089}\x{908A}\x{908B}\x{908C}\x{908D}\x{908E}\x{908F}\x{9090}\x{9091}' - . '\x{9092}\x{9093}\x{9094}\x{9095}\x{9096}\x{9097}\x{9098}\x{9099}\x{909A}' - . '\x{909B}\x{909C}\x{909D}\x{909E}\x{909F}\x{90A0}\x{90A1}\x{90A2}\x{90A3}' - . '\x{90A4}\x{90A5}\x{90A6}\x{90A7}\x{90A8}\x{90A9}\x{90AA}\x{90AC}\x{90AD}' - . '\x{90AE}\x{90AF}\x{90B0}\x{90B1}\x{90B2}\x{90B3}\x{90B4}\x{90B5}\x{90B6}' - . '\x{90B7}\x{90B8}\x{90B9}\x{90BA}\x{90BB}\x{90BC}\x{90BD}\x{90BE}\x{90BF}' - . '\x{90C0}\x{90C1}\x{90C2}\x{90C3}\x{90C4}\x{90C5}\x{90C6}\x{90C7}\x{90C8}' - . '\x{90C9}\x{90CA}\x{90CB}\x{90CE}\x{90CF}\x{90D0}\x{90D1}\x{90D3}\x{90D4}' - . '\x{90D5}\x{90D6}\x{90D7}\x{90D8}\x{90D9}\x{90DA}\x{90DB}\x{90DC}\x{90DD}' - . '\x{90DE}\x{90DF}\x{90E0}\x{90E1}\x{90E2}\x{90E3}\x{90E4}\x{90E5}\x{90E6}' - . '\x{90E7}\x{90E8}\x{90E9}\x{90EA}\x{90EB}\x{90EC}\x{90ED}\x{90EE}\x{90EF}' - . '\x{90F0}\x{90F1}\x{90F2}\x{90F3}\x{90F4}\x{90F5}\x{90F7}\x{90F8}\x{90F9}' - . '\x{90FA}\x{90FB}\x{90FC}\x{90FD}\x{90FE}\x{90FF}\x{9100}\x{9101}\x{9102}' - . '\x{9103}\x{9104}\x{9105}\x{9106}\x{9107}\x{9108}\x{9109}\x{910B}\x{910C}' - . '\x{910D}\x{910E}\x{910F}\x{9110}\x{9111}\x{9112}\x{9113}\x{9114}\x{9115}' - . '\x{9116}\x{9117}\x{9118}\x{9119}\x{911A}\x{911B}\x{911C}\x{911D}\x{911E}' - . '\x{911F}\x{9120}\x{9121}\x{9122}\x{9123}\x{9124}\x{9125}\x{9126}\x{9127}' - . '\x{9128}\x{9129}\x{912A}\x{912B}\x{912C}\x{912D}\x{912E}\x{912F}\x{9130}' - . '\x{9131}\x{9132}\x{9133}\x{9134}\x{9135}\x{9136}\x{9137}\x{9138}\x{9139}' - . '\x{913A}\x{913B}\x{913E}\x{913F}\x{9140}\x{9141}\x{9142}\x{9143}\x{9144}' - . '\x{9145}\x{9146}\x{9147}\x{9148}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}' - . '\x{914E}\x{914F}\x{9150}\x{9151}\x{9152}\x{9153}\x{9154}\x{9155}\x{9156}' - . '\x{9157}\x{9158}\x{915A}\x{915B}\x{915C}\x{915D}\x{915E}\x{915F}\x{9160}' - . '\x{9161}\x{9162}\x{9163}\x{9164}\x{9165}\x{9166}\x{9167}\x{9168}\x{9169}' - . '\x{916A}\x{916B}\x{916C}\x{916D}\x{916E}\x{916F}\x{9170}\x{9171}\x{9172}' - . '\x{9173}\x{9174}\x{9175}\x{9176}\x{9177}\x{9178}\x{9179}\x{917A}\x{917C}' - . '\x{917D}\x{917E}\x{917F}\x{9180}\x{9181}\x{9182}\x{9183}\x{9184}\x{9185}' - . '\x{9186}\x{9187}\x{9188}\x{9189}\x{918A}\x{918B}\x{918C}\x{918D}\x{918E}' - . '\x{918F}\x{9190}\x{9191}\x{9192}\x{9193}\x{9194}\x{9196}\x{9199}\x{919A}' - . '\x{919B}\x{919C}\x{919D}\x{919E}\x{919F}\x{91A0}\x{91A1}\x{91A2}\x{91A3}' - . '\x{91A5}\x{91A6}\x{91A7}\x{91A8}\x{91AA}\x{91AB}\x{91AC}\x{91AD}\x{91AE}' - . '\x{91AF}\x{91B0}\x{91B1}\x{91B2}\x{91B3}\x{91B4}\x{91B5}\x{91B6}\x{91B7}' - . '\x{91B9}\x{91BA}\x{91BB}\x{91BC}\x{91BD}\x{91BE}\x{91C0}\x{91C1}\x{91C2}' - . '\x{91C3}\x{91C5}\x{91C6}\x{91C7}\x{91C9}\x{91CA}\x{91CB}\x{91CC}\x{91CD}' - . '\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D2}\x{91D3}\x{91D4}\x{91D5}\x{91D7}' - . '\x{91D8}\x{91D9}\x{91DA}\x{91DB}\x{91DC}\x{91DD}\x{91DE}\x{91DF}\x{91E2}' - . '\x{91E3}\x{91E4}\x{91E5}\x{91E6}\x{91E7}\x{91E8}\x{91E9}\x{91EA}\x{91EB}' - . '\x{91EC}\x{91ED}\x{91EE}\x{91F0}\x{91F1}\x{91F2}\x{91F3}\x{91F4}\x{91F5}' - . '\x{91F7}\x{91F8}\x{91F9}\x{91FA}\x{91FB}\x{91FD}\x{91FE}\x{91FF}\x{9200}' - . '\x{9201}\x{9202}\x{9203}\x{9204}\x{9205}\x{9206}\x{9207}\x{9208}\x{9209}' - . '\x{920A}\x{920B}\x{920C}\x{920D}\x{920E}\x{920F}\x{9210}\x{9211}\x{9212}' - . '\x{9214}\x{9215}\x{9216}\x{9217}\x{9218}\x{9219}\x{921A}\x{921B}\x{921C}' - . '\x{921D}\x{921E}\x{9220}\x{9221}\x{9223}\x{9224}\x{9225}\x{9226}\x{9227}' - . '\x{9228}\x{9229}\x{922A}\x{922B}\x{922D}\x{922E}\x{922F}\x{9230}\x{9231}' - . '\x{9232}\x{9233}\x{9234}\x{9235}\x{9236}\x{9237}\x{9238}\x{9239}\x{923A}' - . '\x{923B}\x{923C}\x{923D}\x{923E}\x{923F}\x{9240}\x{9241}\x{9242}\x{9245}' - . '\x{9246}\x{9247}\x{9248}\x{9249}\x{924A}\x{924B}\x{924C}\x{924D}\x{924E}' - . '\x{924F}\x{9250}\x{9251}\x{9252}\x{9253}\x{9254}\x{9255}\x{9256}\x{9257}' - . '\x{9258}\x{9259}\x{925A}\x{925B}\x{925C}\x{925D}\x{925E}\x{925F}\x{9260}' - . '\x{9261}\x{9262}\x{9263}\x{9264}\x{9265}\x{9266}\x{9267}\x{9268}\x{926B}' - . '\x{926C}\x{926D}\x{926E}\x{926F}\x{9270}\x{9272}\x{9273}\x{9274}\x{9275}' - . '\x{9276}\x{9277}\x{9278}\x{9279}\x{927A}\x{927B}\x{927C}\x{927D}\x{927E}' - . '\x{927F}\x{9280}\x{9282}\x{9283}\x{9285}\x{9286}\x{9287}\x{9288}\x{9289}' - . '\x{928A}\x{928B}\x{928C}\x{928D}\x{928E}\x{928F}\x{9290}\x{9291}\x{9292}' - . '\x{9293}\x{9294}\x{9295}\x{9296}\x{9297}\x{9298}\x{9299}\x{929A}\x{929B}' - . '\x{929C}\x{929D}\x{929F}\x{92A0}\x{92A1}\x{92A2}\x{92A3}\x{92A4}\x{92A5}' - . '\x{92A6}\x{92A7}\x{92A8}\x{92A9}\x{92AA}\x{92AB}\x{92AC}\x{92AD}\x{92AE}' - . '\x{92AF}\x{92B0}\x{92B1}\x{92B2}\x{92B3}\x{92B4}\x{92B5}\x{92B6}\x{92B7}' - . '\x{92B8}\x{92B9}\x{92BA}\x{92BB}\x{92BC}\x{92BE}\x{92BF}\x{92C0}\x{92C1}' - . '\x{92C2}\x{92C3}\x{92C4}\x{92C5}\x{92C6}\x{92C7}\x{92C8}\x{92C9}\x{92CA}' - . '\x{92CB}\x{92CC}\x{92CD}\x{92CE}\x{92CF}\x{92D0}\x{92D1}\x{92D2}\x{92D3}' - . '\x{92D5}\x{92D6}\x{92D7}\x{92D8}\x{92D9}\x{92DA}\x{92DC}\x{92DD}\x{92DE}' - . '\x{92DF}\x{92E0}\x{92E1}\x{92E3}\x{92E4}\x{92E5}\x{92E6}\x{92E7}\x{92E8}' - . '\x{92E9}\x{92EA}\x{92EB}\x{92EC}\x{92ED}\x{92EE}\x{92EF}\x{92F0}\x{92F1}' - . '\x{92F2}\x{92F3}\x{92F4}\x{92F5}\x{92F6}\x{92F7}\x{92F8}\x{92F9}\x{92FA}' - . '\x{92FB}\x{92FC}\x{92FD}\x{92FE}\x{92FF}\x{9300}\x{9301}\x{9302}\x{9303}' - . '\x{9304}\x{9305}\x{9306}\x{9307}\x{9308}\x{9309}\x{930A}\x{930B}\x{930C}' - . '\x{930D}\x{930E}\x{930F}\x{9310}\x{9311}\x{9312}\x{9313}\x{9314}\x{9315}' - . '\x{9316}\x{9317}\x{9318}\x{9319}\x{931A}\x{931B}\x{931D}\x{931E}\x{931F}' - . '\x{9320}\x{9321}\x{9322}\x{9323}\x{9324}\x{9325}\x{9326}\x{9327}\x{9328}' - . '\x{9329}\x{932A}\x{932B}\x{932D}\x{932E}\x{932F}\x{9332}\x{9333}\x{9334}' - . '\x{9335}\x{9336}\x{9337}\x{9338}\x{9339}\x{933A}\x{933B}\x{933C}\x{933D}' - . '\x{933E}\x{933F}\x{9340}\x{9341}\x{9342}\x{9343}\x{9344}\x{9345}\x{9346}' - . '\x{9347}\x{9348}\x{9349}\x{934A}\x{934B}\x{934C}\x{934D}\x{934E}\x{934F}' - . '\x{9350}\x{9351}\x{9352}\x{9353}\x{9354}\x{9355}\x{9356}\x{9357}\x{9358}' - . '\x{9359}\x{935A}\x{935B}\x{935C}\x{935D}\x{935E}\x{935F}\x{9360}\x{9361}' - . '\x{9363}\x{9364}\x{9365}\x{9366}\x{9367}\x{9369}\x{936A}\x{936C}\x{936D}' - . '\x{936E}\x{9370}\x{9371}\x{9372}\x{9374}\x{9375}\x{9376}\x{9377}\x{9379}' - . '\x{937A}\x{937B}\x{937C}\x{937D}\x{937E}\x{9380}\x{9382}\x{9383}\x{9384}' - . '\x{9385}\x{9386}\x{9387}\x{9388}\x{9389}\x{938A}\x{938C}\x{938D}\x{938E}' - . '\x{938F}\x{9390}\x{9391}\x{9392}\x{9393}\x{9394}\x{9395}\x{9396}\x{9397}' - . '\x{9398}\x{9399}\x{939A}\x{939B}\x{939D}\x{939E}\x{939F}\x{93A1}\x{93A2}' - . '\x{93A3}\x{93A4}\x{93A5}\x{93A6}\x{93A7}\x{93A8}\x{93A9}\x{93AA}\x{93AC}' - . '\x{93AD}\x{93AE}\x{93AF}\x{93B0}\x{93B1}\x{93B2}\x{93B3}\x{93B4}\x{93B5}' - . '\x{93B6}\x{93B7}\x{93B8}\x{93B9}\x{93BA}\x{93BC}\x{93BD}\x{93BE}\x{93BF}' - . '\x{93C0}\x{93C1}\x{93C2}\x{93C3}\x{93C4}\x{93C5}\x{93C6}\x{93C7}\x{93C8}' - . '\x{93C9}\x{93CA}\x{93CB}\x{93CC}\x{93CD}\x{93CE}\x{93CF}\x{93D0}\x{93D1}' - . '\x{93D2}\x{93D3}\x{93D4}\x{93D5}\x{93D6}\x{93D7}\x{93D8}\x{93D9}\x{93DA}' - . '\x{93DB}\x{93DC}\x{93DD}\x{93DE}\x{93DF}\x{93E1}\x{93E2}\x{93E3}\x{93E4}' - . '\x{93E6}\x{93E7}\x{93E8}\x{93E9}\x{93EA}\x{93EB}\x{93EC}\x{93ED}\x{93EE}' - . '\x{93EF}\x{93F0}\x{93F1}\x{93F2}\x{93F4}\x{93F5}\x{93F6}\x{93F7}\x{93F8}' - . '\x{93F9}\x{93FA}\x{93FB}\x{93FC}\x{93FD}\x{93FE}\x{93FF}\x{9400}\x{9401}' - . '\x{9403}\x{9404}\x{9405}\x{9406}\x{9407}\x{9408}\x{9409}\x{940A}\x{940B}' - . '\x{940C}\x{940D}\x{940E}\x{940F}\x{9410}\x{9411}\x{9412}\x{9413}\x{9414}' - . '\x{9415}\x{9416}\x{9418}\x{9419}\x{941B}\x{941D}\x{9420}\x{9422}\x{9423}' - . '\x{9425}\x{9426}\x{9427}\x{9428}\x{9429}\x{942A}\x{942B}\x{942C}\x{942D}' - . '\x{942E}\x{942F}\x{9430}\x{9431}\x{9432}\x{9433}\x{9434}\x{9435}\x{9436}' - . '\x{9437}\x{9438}\x{9439}\x{943A}\x{943B}\x{943C}\x{943D}\x{943E}\x{943F}' - . '\x{9440}\x{9441}\x{9442}\x{9444}\x{9445}\x{9446}\x{9447}\x{9448}\x{9449}' - . '\x{944A}\x{944B}\x{944C}\x{944D}\x{944F}\x{9450}\x{9451}\x{9452}\x{9453}' - . '\x{9454}\x{9455}\x{9456}\x{9457}\x{9458}\x{9459}\x{945B}\x{945C}\x{945D}' - . '\x{945E}\x{945F}\x{9460}\x{9461}\x{9462}\x{9463}\x{9464}\x{9465}\x{9466}' - . '\x{9467}\x{9468}\x{9469}\x{946A}\x{946B}\x{946D}\x{946E}\x{946F}\x{9470}' - . '\x{9471}\x{9472}\x{9473}\x{9474}\x{9475}\x{9476}\x{9477}\x{9478}\x{9479}' - . '\x{947A}\x{947C}\x{947D}\x{947E}\x{947F}\x{9480}\x{9481}\x{9482}\x{9483}' - . '\x{9484}\x{9485}\x{9486}\x{9487}\x{9488}\x{9489}\x{948A}\x{948B}\x{948C}' - . '\x{948D}\x{948E}\x{948F}\x{9490}\x{9491}\x{9492}\x{9493}\x{9494}\x{9495}' - . '\x{9496}\x{9497}\x{9498}\x{9499}\x{949A}\x{949B}\x{949C}\x{949D}\x{949E}' - . '\x{949F}\x{94A0}\x{94A1}\x{94A2}\x{94A3}\x{94A4}\x{94A5}\x{94A6}\x{94A7}' - . '\x{94A8}\x{94A9}\x{94AA}\x{94AB}\x{94AC}\x{94AD}\x{94AE}\x{94AF}\x{94B0}' - . '\x{94B1}\x{94B2}\x{94B3}\x{94B4}\x{94B5}\x{94B6}\x{94B7}\x{94B8}\x{94B9}' - . '\x{94BA}\x{94BB}\x{94BC}\x{94BD}\x{94BE}\x{94BF}\x{94C0}\x{94C1}\x{94C2}' - . '\x{94C3}\x{94C4}\x{94C5}\x{94C6}\x{94C7}\x{94C8}\x{94C9}\x{94CA}\x{94CB}' - . '\x{94CC}\x{94CD}\x{94CE}\x{94CF}\x{94D0}\x{94D1}\x{94D2}\x{94D3}\x{94D4}' - . '\x{94D5}\x{94D6}\x{94D7}\x{94D8}\x{94D9}\x{94DA}\x{94DB}\x{94DC}\x{94DD}' - . '\x{94DE}\x{94DF}\x{94E0}\x{94E1}\x{94E2}\x{94E3}\x{94E4}\x{94E5}\x{94E6}' - . '\x{94E7}\x{94E8}\x{94E9}\x{94EA}\x{94EB}\x{94EC}\x{94ED}\x{94EE}\x{94EF}' - . '\x{94F0}\x{94F1}\x{94F2}\x{94F3}\x{94F4}\x{94F5}\x{94F6}\x{94F7}\x{94F8}' - . '\x{94F9}\x{94FA}\x{94FB}\x{94FC}\x{94FD}\x{94FE}\x{94FF}\x{9500}\x{9501}' - . '\x{9502}\x{9503}\x{9504}\x{9505}\x{9506}\x{9507}\x{9508}\x{9509}\x{950A}' - . '\x{950B}\x{950C}\x{950D}\x{950E}\x{950F}\x{9510}\x{9511}\x{9512}\x{9513}' - . '\x{9514}\x{9515}\x{9516}\x{9517}\x{9518}\x{9519}\x{951A}\x{951B}\x{951C}' - . '\x{951D}\x{951E}\x{951F}\x{9520}\x{9521}\x{9522}\x{9523}\x{9524}\x{9525}' - . '\x{9526}\x{9527}\x{9528}\x{9529}\x{952A}\x{952B}\x{952C}\x{952D}\x{952E}' - . '\x{952F}\x{9530}\x{9531}\x{9532}\x{9533}\x{9534}\x{9535}\x{9536}\x{9537}' - . '\x{9538}\x{9539}\x{953A}\x{953B}\x{953C}\x{953D}\x{953E}\x{953F}\x{9540}' - . '\x{9541}\x{9542}\x{9543}\x{9544}\x{9545}\x{9546}\x{9547}\x{9548}\x{9549}' - . '\x{954A}\x{954B}\x{954C}\x{954D}\x{954E}\x{954F}\x{9550}\x{9551}\x{9552}' - . '\x{9553}\x{9554}\x{9555}\x{9556}\x{9557}\x{9558}\x{9559}\x{955A}\x{955B}' - . '\x{955C}\x{955D}\x{955E}\x{955F}\x{9560}\x{9561}\x{9562}\x{9563}\x{9564}' - . '\x{9565}\x{9566}\x{9567}\x{9568}\x{9569}\x{956A}\x{956B}\x{956C}\x{956D}' - . '\x{956E}\x{956F}\x{9570}\x{9571}\x{9572}\x{9573}\x{9574}\x{9575}\x{9576}' - . '\x{9577}\x{957A}\x{957B}\x{957C}\x{957D}\x{957F}\x{9580}\x{9581}\x{9582}' - . '\x{9583}\x{9584}\x{9586}\x{9587}\x{9588}\x{9589}\x{958A}\x{958B}\x{958C}' - . '\x{958D}\x{958E}\x{958F}\x{9590}\x{9591}\x{9592}\x{9593}\x{9594}\x{9595}' - . '\x{9596}\x{9598}\x{9599}\x{959A}\x{959B}\x{959C}\x{959D}\x{959E}\x{959F}' - . '\x{95A1}\x{95A2}\x{95A3}\x{95A4}\x{95A5}\x{95A6}\x{95A7}\x{95A8}\x{95A9}' - . '\x{95AA}\x{95AB}\x{95AC}\x{95AD}\x{95AE}\x{95AF}\x{95B0}\x{95B1}\x{95B2}' - . '\x{95B5}\x{95B6}\x{95B7}\x{95B9}\x{95BA}\x{95BB}\x{95BC}\x{95BD}\x{95BE}' - . '\x{95BF}\x{95C0}\x{95C2}\x{95C3}\x{95C4}\x{95C5}\x{95C6}\x{95C7}\x{95C8}' - . '\x{95C9}\x{95CA}\x{95CB}\x{95CC}\x{95CD}\x{95CE}\x{95CF}\x{95D0}\x{95D1}' - . '\x{95D2}\x{95D3}\x{95D4}\x{95D5}\x{95D6}\x{95D7}\x{95D8}\x{95DA}\x{95DB}' - . '\x{95DC}\x{95DE}\x{95DF}\x{95E0}\x{95E1}\x{95E2}\x{95E3}\x{95E4}\x{95E5}' - . '\x{95E6}\x{95E7}\x{95E8}\x{95E9}\x{95EA}\x{95EB}\x{95EC}\x{95ED}\x{95EE}' - . '\x{95EF}\x{95F0}\x{95F1}\x{95F2}\x{95F3}\x{95F4}\x{95F5}\x{95F6}\x{95F7}' - . '\x{95F8}\x{95F9}\x{95FA}\x{95FB}\x{95FC}\x{95FD}\x{95FE}\x{95FF}\x{9600}' - . '\x{9601}\x{9602}\x{9603}\x{9604}\x{9605}\x{9606}\x{9607}\x{9608}\x{9609}' - . '\x{960A}\x{960B}\x{960C}\x{960D}\x{960E}\x{960F}\x{9610}\x{9611}\x{9612}' - . '\x{9613}\x{9614}\x{9615}\x{9616}\x{9617}\x{9618}\x{9619}\x{961A}\x{961B}' - . '\x{961C}\x{961D}\x{961E}\x{961F}\x{9620}\x{9621}\x{9622}\x{9623}\x{9624}' - . '\x{9627}\x{9628}\x{962A}\x{962B}\x{962C}\x{962D}\x{962E}\x{962F}\x{9630}' - . '\x{9631}\x{9632}\x{9633}\x{9634}\x{9635}\x{9636}\x{9637}\x{9638}\x{9639}' - . '\x{963A}\x{963B}\x{963C}\x{963D}\x{963F}\x{9640}\x{9641}\x{9642}\x{9643}' - . '\x{9644}\x{9645}\x{9646}\x{9647}\x{9648}\x{9649}\x{964A}\x{964B}\x{964C}' - . '\x{964D}\x{964E}\x{964F}\x{9650}\x{9651}\x{9652}\x{9653}\x{9654}\x{9655}' - . '\x{9658}\x{9659}\x{965A}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9660}' - . '\x{9661}\x{9662}\x{9663}\x{9664}\x{9666}\x{9667}\x{9668}\x{9669}\x{966A}' - . '\x{966B}\x{966C}\x{966D}\x{966E}\x{966F}\x{9670}\x{9671}\x{9672}\x{9673}' - . '\x{9674}\x{9675}\x{9676}\x{9677}\x{9678}\x{967C}\x{967D}\x{967E}\x{9680}' - . '\x{9683}\x{9684}\x{9685}\x{9686}\x{9687}\x{9688}\x{9689}\x{968A}\x{968B}' - . '\x{968D}\x{968E}\x{968F}\x{9690}\x{9691}\x{9692}\x{9693}\x{9694}\x{9695}' - . '\x{9697}\x{9698}\x{9699}\x{969B}\x{969C}\x{969E}\x{96A0}\x{96A1}\x{96A2}' - . '\x{96A3}\x{96A4}\x{96A5}\x{96A6}\x{96A7}\x{96A8}\x{96A9}\x{96AA}\x{96AC}' - . '\x{96AD}\x{96AE}\x{96B0}\x{96B1}\x{96B3}\x{96B4}\x{96B6}\x{96B7}\x{96B8}' - . '\x{96B9}\x{96BA}\x{96BB}\x{96BC}\x{96BD}\x{96BE}\x{96BF}\x{96C0}\x{96C1}' - . '\x{96C2}\x{96C3}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C8}\x{96C9}\x{96CA}' - . '\x{96CB}\x{96CC}\x{96CD}\x{96CE}\x{96CF}\x{96D0}\x{96D1}\x{96D2}\x{96D3}' - . '\x{96D4}\x{96D5}\x{96D6}\x{96D7}\x{96D8}\x{96D9}\x{96DA}\x{96DB}\x{96DC}' - . '\x{96DD}\x{96DE}\x{96DF}\x{96E0}\x{96E1}\x{96E2}\x{96E3}\x{96E5}\x{96E8}' - . '\x{96E9}\x{96EA}\x{96EB}\x{96EC}\x{96ED}\x{96EE}\x{96EF}\x{96F0}\x{96F1}' - . '\x{96F2}\x{96F3}\x{96F4}\x{96F5}\x{96F6}\x{96F7}\x{96F8}\x{96F9}\x{96FA}' - . '\x{96FB}\x{96FD}\x{96FE}\x{96FF}\x{9700}\x{9701}\x{9702}\x{9703}\x{9704}' - . '\x{9705}\x{9706}\x{9707}\x{9708}\x{9709}\x{970A}\x{970B}\x{970C}\x{970D}' - . '\x{970E}\x{970F}\x{9710}\x{9711}\x{9712}\x{9713}\x{9715}\x{9716}\x{9718}' - . '\x{9719}\x{971C}\x{971D}\x{971E}\x{971F}\x{9720}\x{9721}\x{9722}\x{9723}' - . '\x{9724}\x{9725}\x{9726}\x{9727}\x{9728}\x{9729}\x{972A}\x{972B}\x{972C}' - . '\x{972D}\x{972E}\x{972F}\x{9730}\x{9731}\x{9732}\x{9735}\x{9736}\x{9738}' - . '\x{9739}\x{973A}\x{973B}\x{973C}\x{973D}\x{973E}\x{973F}\x{9742}\x{9743}' - . '\x{9744}\x{9745}\x{9746}\x{9747}\x{9748}\x{9749}\x{974A}\x{974B}\x{974C}' - . '\x{974E}\x{974F}\x{9750}\x{9751}\x{9752}\x{9753}\x{9754}\x{9755}\x{9756}' - . '\x{9758}\x{9759}\x{975A}\x{975B}\x{975C}\x{975D}\x{975E}\x{975F}\x{9760}' - . '\x{9761}\x{9762}\x{9765}\x{9766}\x{9767}\x{9768}\x{9769}\x{976A}\x{976B}' - . '\x{976C}\x{976D}\x{976E}\x{976F}\x{9770}\x{9772}\x{9773}\x{9774}\x{9776}' - . '\x{9777}\x{9778}\x{9779}\x{977A}\x{977B}\x{977C}\x{977D}\x{977E}\x{977F}' - . '\x{9780}\x{9781}\x{9782}\x{9783}\x{9784}\x{9785}\x{9786}\x{9788}\x{978A}' - . '\x{978B}\x{978C}\x{978D}\x{978E}\x{978F}\x{9790}\x{9791}\x{9792}\x{9793}' - . '\x{9794}\x{9795}\x{9796}\x{9797}\x{9798}\x{9799}\x{979A}\x{979C}\x{979D}' - . '\x{979E}\x{979F}\x{97A0}\x{97A1}\x{97A2}\x{97A3}\x{97A4}\x{97A5}\x{97A6}' - . '\x{97A7}\x{97A8}\x{97AA}\x{97AB}\x{97AC}\x{97AD}\x{97AE}\x{97AF}\x{97B2}' - . '\x{97B3}\x{97B4}\x{97B6}\x{97B7}\x{97B8}\x{97B9}\x{97BA}\x{97BB}\x{97BC}' - . '\x{97BD}\x{97BF}\x{97C1}\x{97C2}\x{97C3}\x{97C4}\x{97C5}\x{97C6}\x{97C7}' - . '\x{97C8}\x{97C9}\x{97CA}\x{97CB}\x{97CC}\x{97CD}\x{97CE}\x{97CF}\x{97D0}' - . '\x{97D1}\x{97D3}\x{97D4}\x{97D5}\x{97D6}\x{97D7}\x{97D8}\x{97D9}\x{97DA}' - . '\x{97DB}\x{97DC}\x{97DD}\x{97DE}\x{97DF}\x{97E0}\x{97E1}\x{97E2}\x{97E3}' - . '\x{97E4}\x{97E5}\x{97E6}\x{97E7}\x{97E8}\x{97E9}\x{97EA}\x{97EB}\x{97EC}' - . '\x{97ED}\x{97EE}\x{97EF}\x{97F0}\x{97F1}\x{97F2}\x{97F3}\x{97F4}\x{97F5}' - . '\x{97F6}\x{97F7}\x{97F8}\x{97F9}\x{97FA}\x{97FB}\x{97FD}\x{97FE}\x{97FF}' - . '\x{9800}\x{9801}\x{9802}\x{9803}\x{9804}\x{9805}\x{9806}\x{9807}\x{9808}' - . '\x{9809}\x{980A}\x{980B}\x{980C}\x{980D}\x{980E}\x{980F}\x{9810}\x{9811}' - . '\x{9812}\x{9813}\x{9814}\x{9815}\x{9816}\x{9817}\x{9818}\x{9819}\x{981A}' - . '\x{981B}\x{981C}\x{981D}\x{981E}\x{9820}\x{9821}\x{9822}\x{9823}\x{9824}' - . '\x{9826}\x{9827}\x{9828}\x{9829}\x{982B}\x{982D}\x{982E}\x{982F}\x{9830}' - . '\x{9831}\x{9832}\x{9834}\x{9835}\x{9836}\x{9837}\x{9838}\x{9839}\x{983B}' - . '\x{983C}\x{983D}\x{983F}\x{9840}\x{9841}\x{9843}\x{9844}\x{9845}\x{9846}' - . '\x{9848}\x{9849}\x{984A}\x{984C}\x{984D}\x{984E}\x{984F}\x{9850}\x{9851}' - . '\x{9852}\x{9853}\x{9854}\x{9855}\x{9857}\x{9858}\x{9859}\x{985A}\x{985B}' - . '\x{985C}\x{985D}\x{985E}\x{985F}\x{9860}\x{9861}\x{9862}\x{9863}\x{9864}' - . '\x{9865}\x{9867}\x{9869}\x{986A}\x{986B}\x{986C}\x{986D}\x{986E}\x{986F}' - . '\x{9870}\x{9871}\x{9872}\x{9873}\x{9874}\x{9875}\x{9876}\x{9877}\x{9878}' - . '\x{9879}\x{987A}\x{987B}\x{987C}\x{987D}\x{987E}\x{987F}\x{9880}\x{9881}' - . '\x{9882}\x{9883}\x{9884}\x{9885}\x{9886}\x{9887}\x{9888}\x{9889}\x{988A}' - . '\x{988B}\x{988C}\x{988D}\x{988E}\x{988F}\x{9890}\x{9891}\x{9892}\x{9893}' - . '\x{9894}\x{9895}\x{9896}\x{9897}\x{9898}\x{9899}\x{989A}\x{989B}\x{989C}' - . '\x{989D}\x{989E}\x{989F}\x{98A0}\x{98A1}\x{98A2}\x{98A3}\x{98A4}\x{98A5}' - . '\x{98A6}\x{98A7}\x{98A8}\x{98A9}\x{98AA}\x{98AB}\x{98AC}\x{98AD}\x{98AE}' - . '\x{98AF}\x{98B0}\x{98B1}\x{98B2}\x{98B3}\x{98B4}\x{98B5}\x{98B6}\x{98B8}' - . '\x{98B9}\x{98BA}\x{98BB}\x{98BC}\x{98BD}\x{98BE}\x{98BF}\x{98C0}\x{98C1}' - . '\x{98C2}\x{98C3}\x{98C4}\x{98C5}\x{98C6}\x{98C8}\x{98C9}\x{98CB}\x{98CC}' - . '\x{98CD}\x{98CE}\x{98CF}\x{98D0}\x{98D1}\x{98D2}\x{98D3}\x{98D4}\x{98D5}' - . '\x{98D6}\x{98D7}\x{98D8}\x{98D9}\x{98DA}\x{98DB}\x{98DC}\x{98DD}\x{98DE}' - . '\x{98DF}\x{98E0}\x{98E2}\x{98E3}\x{98E5}\x{98E6}\x{98E7}\x{98E8}\x{98E9}' - . '\x{98EA}\x{98EB}\x{98ED}\x{98EF}\x{98F0}\x{98F2}\x{98F3}\x{98F4}\x{98F5}' - . '\x{98F6}\x{98F7}\x{98F9}\x{98FA}\x{98FC}\x{98FD}\x{98FE}\x{98FF}\x{9900}' - . '\x{9901}\x{9902}\x{9903}\x{9904}\x{9905}\x{9906}\x{9907}\x{9908}\x{9909}' - . '\x{990A}\x{990B}\x{990C}\x{990D}\x{990E}\x{990F}\x{9910}\x{9911}\x{9912}' - . '\x{9913}\x{9914}\x{9915}\x{9916}\x{9917}\x{9918}\x{991A}\x{991B}\x{991C}' - . '\x{991D}\x{991E}\x{991F}\x{9920}\x{9921}\x{9922}\x{9923}\x{9924}\x{9925}' - . '\x{9926}\x{9927}\x{9928}\x{9929}\x{992A}\x{992B}\x{992C}\x{992D}\x{992E}' - . '\x{992F}\x{9930}\x{9931}\x{9932}\x{9933}\x{9934}\x{9935}\x{9936}\x{9937}' - . '\x{9938}\x{9939}\x{993A}\x{993C}\x{993D}\x{993E}\x{993F}\x{9940}\x{9941}' - . '\x{9942}\x{9943}\x{9945}\x{9946}\x{9947}\x{9948}\x{9949}\x{994A}\x{994B}' - . '\x{994C}\x{994E}\x{994F}\x{9950}\x{9951}\x{9952}\x{9953}\x{9954}\x{9955}' - . '\x{9956}\x{9957}\x{9958}\x{9959}\x{995B}\x{995C}\x{995E}\x{995F}\x{9960}' - . '\x{9961}\x{9962}\x{9963}\x{9964}\x{9965}\x{9966}\x{9967}\x{9968}\x{9969}' - . '\x{996A}\x{996B}\x{996C}\x{996D}\x{996E}\x{996F}\x{9970}\x{9971}\x{9972}' - . '\x{9973}\x{9974}\x{9975}\x{9976}\x{9977}\x{9978}\x{9979}\x{997A}\x{997B}' - . '\x{997C}\x{997D}\x{997E}\x{997F}\x{9980}\x{9981}\x{9982}\x{9983}\x{9984}' - . '\x{9985}\x{9986}\x{9987}\x{9988}\x{9989}\x{998A}\x{998B}\x{998C}\x{998D}' - . '\x{998E}\x{998F}\x{9990}\x{9991}\x{9992}\x{9993}\x{9994}\x{9995}\x{9996}' - . '\x{9997}\x{9998}\x{9999}\x{999A}\x{999B}\x{999C}\x{999D}\x{999E}\x{999F}' - . '\x{99A0}\x{99A1}\x{99A2}\x{99A3}\x{99A4}\x{99A5}\x{99A6}\x{99A7}\x{99A8}' - . '\x{99A9}\x{99AA}\x{99AB}\x{99AC}\x{99AD}\x{99AE}\x{99AF}\x{99B0}\x{99B1}' - . '\x{99B2}\x{99B3}\x{99B4}\x{99B5}\x{99B6}\x{99B7}\x{99B8}\x{99B9}\x{99BA}' - . '\x{99BB}\x{99BC}\x{99BD}\x{99BE}\x{99C0}\x{99C1}\x{99C2}\x{99C3}\x{99C4}' - . '\x{99C6}\x{99C7}\x{99C8}\x{99C9}\x{99CA}\x{99CB}\x{99CC}\x{99CD}\x{99CE}' - . '\x{99CF}\x{99D0}\x{99D1}\x{99D2}\x{99D3}\x{99D4}\x{99D5}\x{99D6}\x{99D7}' - . '\x{99D8}\x{99D9}\x{99DA}\x{99DB}\x{99DC}\x{99DD}\x{99DE}\x{99DF}\x{99E1}' - . '\x{99E2}\x{99E3}\x{99E4}\x{99E5}\x{99E7}\x{99E8}\x{99E9}\x{99EA}\x{99EC}' - . '\x{99ED}\x{99EE}\x{99EF}\x{99F0}\x{99F1}\x{99F2}\x{99F3}\x{99F4}\x{99F6}' - . '\x{99F7}\x{99F8}\x{99F9}\x{99FA}\x{99FB}\x{99FC}\x{99FD}\x{99FE}\x{99FF}' - . '\x{9A00}\x{9A01}\x{9A02}\x{9A03}\x{9A04}\x{9A05}\x{9A06}\x{9A07}\x{9A08}' - . '\x{9A09}\x{9A0A}\x{9A0B}\x{9A0C}\x{9A0D}\x{9A0E}\x{9A0F}\x{9A11}\x{9A14}' - . '\x{9A15}\x{9A16}\x{9A19}\x{9A1A}\x{9A1B}\x{9A1C}\x{9A1D}\x{9A1E}\x{9A1F}' - . '\x{9A20}\x{9A21}\x{9A22}\x{9A23}\x{9A24}\x{9A25}\x{9A26}\x{9A27}\x{9A29}' - . '\x{9A2A}\x{9A2B}\x{9A2C}\x{9A2D}\x{9A2E}\x{9A2F}\x{9A30}\x{9A31}\x{9A32}' - . '\x{9A33}\x{9A34}\x{9A35}\x{9A36}\x{9A37}\x{9A38}\x{9A39}\x{9A3A}\x{9A3C}' - . '\x{9A3D}\x{9A3E}\x{9A3F}\x{9A40}\x{9A41}\x{9A42}\x{9A43}\x{9A44}\x{9A45}' - . '\x{9A46}\x{9A47}\x{9A48}\x{9A49}\x{9A4A}\x{9A4B}\x{9A4C}\x{9A4D}\x{9A4E}' - . '\x{9A4F}\x{9A50}\x{9A52}\x{9A53}\x{9A54}\x{9A55}\x{9A56}\x{9A57}\x{9A59}' - . '\x{9A5A}\x{9A5B}\x{9A5C}\x{9A5E}\x{9A5F}\x{9A60}\x{9A61}\x{9A62}\x{9A64}' - . '\x{9A65}\x{9A66}\x{9A67}\x{9A68}\x{9A69}\x{9A6A}\x{9A6B}\x{9A6C}\x{9A6D}' - . '\x{9A6E}\x{9A6F}\x{9A70}\x{9A71}\x{9A72}\x{9A73}\x{9A74}\x{9A75}\x{9A76}' - . '\x{9A77}\x{9A78}\x{9A79}\x{9A7A}\x{9A7B}\x{9A7C}\x{9A7D}\x{9A7E}\x{9A7F}' - . '\x{9A80}\x{9A81}\x{9A82}\x{9A83}\x{9A84}\x{9A85}\x{9A86}\x{9A87}\x{9A88}' - . '\x{9A89}\x{9A8A}\x{9A8B}\x{9A8C}\x{9A8D}\x{9A8E}\x{9A8F}\x{9A90}\x{9A91}' - . '\x{9A92}\x{9A93}\x{9A94}\x{9A95}\x{9A96}\x{9A97}\x{9A98}\x{9A99}\x{9A9A}' - . '\x{9A9B}\x{9A9C}\x{9A9D}\x{9A9E}\x{9A9F}\x{9AA0}\x{9AA1}\x{9AA2}\x{9AA3}' - . '\x{9AA4}\x{9AA5}\x{9AA6}\x{9AA7}\x{9AA8}\x{9AAA}\x{9AAB}\x{9AAC}\x{9AAD}' - . '\x{9AAE}\x{9AAF}\x{9AB0}\x{9AB1}\x{9AB2}\x{9AB3}\x{9AB4}\x{9AB5}\x{9AB6}' - . '\x{9AB7}\x{9AB8}\x{9AB9}\x{9ABA}\x{9ABB}\x{9ABC}\x{9ABE}\x{9ABF}\x{9AC0}' - . '\x{9AC1}\x{9AC2}\x{9AC3}\x{9AC4}\x{9AC5}\x{9AC6}\x{9AC7}\x{9AC9}\x{9ACA}' - . '\x{9ACB}\x{9ACC}\x{9ACD}\x{9ACE}\x{9ACF}\x{9AD0}\x{9AD1}\x{9AD2}\x{9AD3}' - . '\x{9AD4}\x{9AD5}\x{9AD6}\x{9AD8}\x{9AD9}\x{9ADA}\x{9ADB}\x{9ADC}\x{9ADD}' - . '\x{9ADE}\x{9ADF}\x{9AE1}\x{9AE2}\x{9AE3}\x{9AE5}\x{9AE6}\x{9AE7}\x{9AEA}' - . '\x{9AEB}\x{9AEC}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF2}\x{9AF3}\x{9AF4}' - . '\x{9AF5}\x{9AF6}\x{9AF7}\x{9AF8}\x{9AF9}\x{9AFA}\x{9AFB}\x{9AFC}\x{9AFD}' - . '\x{9AFE}\x{9AFF}\x{9B01}\x{9B03}\x{9B04}\x{9B05}\x{9B06}\x{9B07}\x{9B08}' - . '\x{9B0A}\x{9B0B}\x{9B0C}\x{9B0D}\x{9B0E}\x{9B0F}\x{9B10}\x{9B11}\x{9B12}' - . '\x{9B13}\x{9B15}\x{9B16}\x{9B17}\x{9B18}\x{9B19}\x{9B1A}\x{9B1C}\x{9B1D}' - . '\x{9B1E}\x{9B1F}\x{9B20}\x{9B21}\x{9B22}\x{9B23}\x{9B24}\x{9B25}\x{9B26}' - . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2B}\x{9B2C}\x{9B2D}\x{9B2E}\x{9B2F}' - . '\x{9B30}\x{9B31}\x{9B32}\x{9B33}\x{9B35}\x{9B36}\x{9B37}\x{9B38}\x{9B39}' - . '\x{9B3A}\x{9B3B}\x{9B3C}\x{9B3E}\x{9B3F}\x{9B41}\x{9B42}\x{9B43}\x{9B44}' - . '\x{9B45}\x{9B46}\x{9B47}\x{9B48}\x{9B49}\x{9B4A}\x{9B4B}\x{9B4C}\x{9B4D}' - . '\x{9B4E}\x{9B4F}\x{9B51}\x{9B52}\x{9B53}\x{9B54}\x{9B55}\x{9B56}\x{9B58}' - . '\x{9B59}\x{9B5A}\x{9B5B}\x{9B5C}\x{9B5D}\x{9B5E}\x{9B5F}\x{9B60}\x{9B61}' - . '\x{9B63}\x{9B64}\x{9B65}\x{9B66}\x{9B67}\x{9B68}\x{9B69}\x{9B6A}\x{9B6B}' - . '\x{9B6C}\x{9B6D}\x{9B6E}\x{9B6F}\x{9B70}\x{9B71}\x{9B73}\x{9B74}\x{9B75}' - . '\x{9B76}\x{9B77}\x{9B78}\x{9B79}\x{9B7A}\x{9B7B}\x{9B7C}\x{9B7D}\x{9B7E}' - . '\x{9B7F}\x{9B80}\x{9B81}\x{9B82}\x{9B83}\x{9B84}\x{9B85}\x{9B86}\x{9B87}' - . '\x{9B88}\x{9B8A}\x{9B8B}\x{9B8D}\x{9B8E}\x{9B8F}\x{9B90}\x{9B91}\x{9B92}' - . '\x{9B93}\x{9B94}\x{9B95}\x{9B96}\x{9B97}\x{9B98}\x{9B9A}\x{9B9B}\x{9B9C}' - . '\x{9B9D}\x{9B9E}\x{9B9F}\x{9BA0}\x{9BA1}\x{9BA2}\x{9BA3}\x{9BA4}\x{9BA5}' - . '\x{9BA6}\x{9BA7}\x{9BA8}\x{9BA9}\x{9BAA}\x{9BAB}\x{9BAC}\x{9BAD}\x{9BAE}' - . '\x{9BAF}\x{9BB0}\x{9BB1}\x{9BB2}\x{9BB3}\x{9BB4}\x{9BB5}\x{9BB6}\x{9BB7}' - . '\x{9BB8}\x{9BB9}\x{9BBA}\x{9BBB}\x{9BBC}\x{9BBD}\x{9BBE}\x{9BBF}\x{9BC0}' - . '\x{9BC1}\x{9BC3}\x{9BC4}\x{9BC5}\x{9BC6}\x{9BC7}\x{9BC8}\x{9BC9}\x{9BCA}' - . '\x{9BCB}\x{9BCC}\x{9BCD}\x{9BCE}\x{9BCF}\x{9BD0}\x{9BD1}\x{9BD2}\x{9BD3}' - . '\x{9BD4}\x{9BD5}\x{9BD6}\x{9BD7}\x{9BD8}\x{9BD9}\x{9BDA}\x{9BDB}\x{9BDC}' - . '\x{9BDD}\x{9BDE}\x{9BDF}\x{9BE0}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}\x{9BE5}' - . '\x{9BE6}\x{9BE7}\x{9BE8}\x{9BE9}\x{9BEA}\x{9BEB}\x{9BEC}\x{9BED}\x{9BEE}' - . '\x{9BEF}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF3}\x{9BF4}\x{9BF5}\x{9BF7}\x{9BF8}' - . '\x{9BF9}\x{9BFA}\x{9BFB}\x{9BFC}\x{9BFD}\x{9BFE}\x{9BFF}\x{9C02}\x{9C05}' - . '\x{9C06}\x{9C07}\x{9C08}\x{9C09}\x{9C0A}\x{9C0B}\x{9C0C}\x{9C0D}\x{9C0E}' - . '\x{9C0F}\x{9C10}\x{9C11}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C16}\x{9C17}' - . '\x{9C18}\x{9C19}\x{9C1A}\x{9C1B}\x{9C1C}\x{9C1D}\x{9C1E}\x{9C1F}\x{9C20}' - . '\x{9C21}\x{9C22}\x{9C23}\x{9C24}\x{9C25}\x{9C26}\x{9C27}\x{9C28}\x{9C29}' - . '\x{9C2A}\x{9C2B}\x{9C2C}\x{9C2D}\x{9C2F}\x{9C30}\x{9C31}\x{9C32}\x{9C33}' - . '\x{9C34}\x{9C35}\x{9C36}\x{9C37}\x{9C38}\x{9C39}\x{9C3A}\x{9C3B}\x{9C3C}' - . '\x{9C3D}\x{9C3E}\x{9C3F}\x{9C40}\x{9C41}\x{9C43}\x{9C44}\x{9C45}\x{9C46}' - . '\x{9C47}\x{9C48}\x{9C49}\x{9C4A}\x{9C4B}\x{9C4C}\x{9C4D}\x{9C4E}\x{9C50}' - . '\x{9C52}\x{9C53}\x{9C54}\x{9C55}\x{9C56}\x{9C57}\x{9C58}\x{9C59}\x{9C5A}' - . '\x{9C5B}\x{9C5C}\x{9C5D}\x{9C5E}\x{9C5F}\x{9C60}\x{9C62}\x{9C63}\x{9C65}' - . '\x{9C66}\x{9C67}\x{9C68}\x{9C69}\x{9C6A}\x{9C6B}\x{9C6C}\x{9C6D}\x{9C6E}' - . '\x{9C6F}\x{9C70}\x{9C71}\x{9C72}\x{9C73}\x{9C74}\x{9C75}\x{9C77}\x{9C78}' - . '\x{9C79}\x{9C7A}\x{9C7C}\x{9C7D}\x{9C7E}\x{9C7F}\x{9C80}\x{9C81}\x{9C82}' - . '\x{9C83}\x{9C84}\x{9C85}\x{9C86}\x{9C87}\x{9C88}\x{9C89}\x{9C8A}\x{9C8B}' - . '\x{9C8C}\x{9C8D}\x{9C8E}\x{9C8F}\x{9C90}\x{9C91}\x{9C92}\x{9C93}\x{9C94}' - . '\x{9C95}\x{9C96}\x{9C97}\x{9C98}\x{9C99}\x{9C9A}\x{9C9B}\x{9C9C}\x{9C9D}' - . '\x{9C9E}\x{9C9F}\x{9CA0}\x{9CA1}\x{9CA2}\x{9CA3}\x{9CA4}\x{9CA5}\x{9CA6}' - . '\x{9CA7}\x{9CA8}\x{9CA9}\x{9CAA}\x{9CAB}\x{9CAC}\x{9CAD}\x{9CAE}\x{9CAF}' - . '\x{9CB0}\x{9CB1}\x{9CB2}\x{9CB3}\x{9CB4}\x{9CB5}\x{9CB6}\x{9CB7}\x{9CB8}' - . '\x{9CB9}\x{9CBA}\x{9CBB}\x{9CBC}\x{9CBD}\x{9CBE}\x{9CBF}\x{9CC0}\x{9CC1}' - . '\x{9CC2}\x{9CC3}\x{9CC4}\x{9CC5}\x{9CC6}\x{9CC7}\x{9CC8}\x{9CC9}\x{9CCA}' - . '\x{9CCB}\x{9CCC}\x{9CCD}\x{9CCE}\x{9CCF}\x{9CD0}\x{9CD1}\x{9CD2}\x{9CD3}' - . '\x{9CD4}\x{9CD5}\x{9CD6}\x{9CD7}\x{9CD8}\x{9CD9}\x{9CDA}\x{9CDB}\x{9CDC}' - . '\x{9CDD}\x{9CDE}\x{9CDF}\x{9CE0}\x{9CE1}\x{9CE2}\x{9CE3}\x{9CE4}\x{9CE5}' - . '\x{9CE6}\x{9CE7}\x{9CE8}\x{9CE9}\x{9CEA}\x{9CEB}\x{9CEC}\x{9CED}\x{9CEE}' - . '\x{9CEF}\x{9CF0}\x{9CF1}\x{9CF2}\x{9CF3}\x{9CF4}\x{9CF5}\x{9CF6}\x{9CF7}' - . '\x{9CF8}\x{9CF9}\x{9CFA}\x{9CFB}\x{9CFC}\x{9CFD}\x{9CFE}\x{9CFF}\x{9D00}' - . '\x{9D01}\x{9D02}\x{9D03}\x{9D04}\x{9D05}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' - . '\x{9D0A}\x{9D0B}\x{9D0F}\x{9D10}\x{9D12}\x{9D13}\x{9D14}\x{9D15}\x{9D16}' - . '\x{9D17}\x{9D18}\x{9D19}\x{9D1A}\x{9D1B}\x{9D1C}\x{9D1D}\x{9D1E}\x{9D1F}' - . '\x{9D20}\x{9D21}\x{9D22}\x{9D23}\x{9D24}\x{9D25}\x{9D26}\x{9D28}\x{9D29}' - . '\x{9D2B}\x{9D2D}\x{9D2E}\x{9D2F}\x{9D30}\x{9D31}\x{9D32}\x{9D33}\x{9D34}' - . '\x{9D36}\x{9D37}\x{9D38}\x{9D39}\x{9D3A}\x{9D3B}\x{9D3D}\x{9D3E}\x{9D3F}' - . '\x{9D40}\x{9D41}\x{9D42}\x{9D43}\x{9D45}\x{9D46}\x{9D47}\x{9D48}\x{9D49}' - . '\x{9D4A}\x{9D4B}\x{9D4C}\x{9D4D}\x{9D4E}\x{9D4F}\x{9D50}\x{9D51}\x{9D52}' - . '\x{9D53}\x{9D54}\x{9D55}\x{9D56}\x{9D57}\x{9D58}\x{9D59}\x{9D5A}\x{9D5B}' - . '\x{9D5C}\x{9D5D}\x{9D5E}\x{9D5F}\x{9D60}\x{9D61}\x{9D62}\x{9D63}\x{9D64}' - . '\x{9D65}\x{9D66}\x{9D67}\x{9D68}\x{9D69}\x{9D6A}\x{9D6B}\x{9D6C}\x{9D6E}' - . '\x{9D6F}\x{9D70}\x{9D71}\x{9D72}\x{9D73}\x{9D74}\x{9D75}\x{9D76}\x{9D77}' - . '\x{9D78}\x{9D79}\x{9D7A}\x{9D7B}\x{9D7C}\x{9D7D}\x{9D7E}\x{9D7F}\x{9D80}' - . '\x{9D81}\x{9D82}\x{9D83}\x{9D84}\x{9D85}\x{9D86}\x{9D87}\x{9D88}\x{9D89}' - . '\x{9D8A}\x{9D8B}\x{9D8C}\x{9D8D}\x{9D8E}\x{9D90}\x{9D91}\x{9D92}\x{9D93}' - . '\x{9D94}\x{9D96}\x{9D97}\x{9D98}\x{9D99}\x{9D9A}\x{9D9B}\x{9D9C}\x{9D9D}' - . '\x{9D9E}\x{9D9F}\x{9DA0}\x{9DA1}\x{9DA2}\x{9DA3}\x{9DA4}\x{9DA5}\x{9DA6}' - . '\x{9DA7}\x{9DA8}\x{9DA9}\x{9DAA}\x{9DAB}\x{9DAC}\x{9DAD}\x{9DAF}\x{9DB0}' - . '\x{9DB1}\x{9DB2}\x{9DB3}\x{9DB4}\x{9DB5}\x{9DB6}\x{9DB7}\x{9DB8}\x{9DB9}' - . '\x{9DBA}\x{9DBB}\x{9DBC}\x{9DBE}\x{9DBF}\x{9DC1}\x{9DC2}\x{9DC3}\x{9DC4}' - . '\x{9DC5}\x{9DC7}\x{9DC8}\x{9DC9}\x{9DCA}\x{9DCB}\x{9DCC}\x{9DCD}\x{9DCE}' - . '\x{9DCF}\x{9DD0}\x{9DD1}\x{9DD2}\x{9DD3}\x{9DD4}\x{9DD5}\x{9DD6}\x{9DD7}' - . '\x{9DD8}\x{9DD9}\x{9DDA}\x{9DDB}\x{9DDC}\x{9DDD}\x{9DDE}\x{9DDF}\x{9DE0}' - . '\x{9DE1}\x{9DE2}\x{9DE3}\x{9DE4}\x{9DE5}\x{9DE6}\x{9DE7}\x{9DE8}\x{9DE9}' - . '\x{9DEB}\x{9DEC}\x{9DED}\x{9DEE}\x{9DEF}\x{9DF0}\x{9DF1}\x{9DF2}\x{9DF3}' - . '\x{9DF4}\x{9DF5}\x{9DF6}\x{9DF7}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFB}\x{9DFD}' - . '\x{9DFE}\x{9DFF}\x{9E00}\x{9E01}\x{9E02}\x{9E03}\x{9E04}\x{9E05}\x{9E06}' - . '\x{9E07}\x{9E08}\x{9E09}\x{9E0A}\x{9E0B}\x{9E0C}\x{9E0D}\x{9E0F}\x{9E10}' - . '\x{9E11}\x{9E12}\x{9E13}\x{9E14}\x{9E15}\x{9E17}\x{9E18}\x{9E19}\x{9E1A}' - . '\x{9E1B}\x{9E1D}\x{9E1E}\x{9E1F}\x{9E20}\x{9E21}\x{9E22}\x{9E23}\x{9E24}' - . '\x{9E25}\x{9E26}\x{9E27}\x{9E28}\x{9E29}\x{9E2A}\x{9E2B}\x{9E2C}\x{9E2D}' - . '\x{9E2E}\x{9E2F}\x{9E30}\x{9E31}\x{9E32}\x{9E33}\x{9E34}\x{9E35}\x{9E36}' - . '\x{9E37}\x{9E38}\x{9E39}\x{9E3A}\x{9E3B}\x{9E3C}\x{9E3D}\x{9E3E}\x{9E3F}' - . '\x{9E40}\x{9E41}\x{9E42}\x{9E43}\x{9E44}\x{9E45}\x{9E46}\x{9E47}\x{9E48}' - . '\x{9E49}\x{9E4A}\x{9E4B}\x{9E4C}\x{9E4D}\x{9E4E}\x{9E4F}\x{9E50}\x{9E51}' - . '\x{9E52}\x{9E53}\x{9E54}\x{9E55}\x{9E56}\x{9E57}\x{9E58}\x{9E59}\x{9E5A}' - . '\x{9E5B}\x{9E5C}\x{9E5D}\x{9E5E}\x{9E5F}\x{9E60}\x{9E61}\x{9E62}\x{9E63}' - . '\x{9E64}\x{9E65}\x{9E66}\x{9E67}\x{9E68}\x{9E69}\x{9E6A}\x{9E6B}\x{9E6C}' - . '\x{9E6D}\x{9E6E}\x{9E6F}\x{9E70}\x{9E71}\x{9E72}\x{9E73}\x{9E74}\x{9E75}' - . '\x{9E76}\x{9E77}\x{9E79}\x{9E7A}\x{9E7C}\x{9E7D}\x{9E7E}\x{9E7F}\x{9E80}' - . '\x{9E81}\x{9E82}\x{9E83}\x{9E84}\x{9E85}\x{9E86}\x{9E87}\x{9E88}\x{9E89}' - . '\x{9E8A}\x{9E8B}\x{9E8C}\x{9E8D}\x{9E8E}\x{9E91}\x{9E92}\x{9E93}\x{9E94}' - . '\x{9E96}\x{9E97}\x{9E99}\x{9E9A}\x{9E9B}\x{9E9C}\x{9E9D}\x{9E9F}\x{9EA0}' - . '\x{9EA1}\x{9EA3}\x{9EA4}\x{9EA5}\x{9EA6}\x{9EA7}\x{9EA8}\x{9EA9}\x{9EAA}' - . '\x{9EAD}\x{9EAE}\x{9EAF}\x{9EB0}\x{9EB2}\x{9EB3}\x{9EB4}\x{9EB5}\x{9EB6}' - . '\x{9EB7}\x{9EB8}\x{9EBB}\x{9EBC}\x{9EBD}\x{9EBE}\x{9EBF}\x{9EC0}\x{9EC1}' - . '\x{9EC2}\x{9EC3}\x{9EC4}\x{9EC5}\x{9EC6}\x{9EC7}\x{9EC8}\x{9EC9}\x{9ECA}' - . '\x{9ECB}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED1}\x{9ED2}\x{9ED3}' - . '\x{9ED4}\x{9ED5}\x{9ED6}\x{9ED7}\x{9ED8}\x{9ED9}\x{9EDA}\x{9EDB}\x{9EDC}' - . '\x{9EDD}\x{9EDE}\x{9EDF}\x{9EE0}\x{9EE1}\x{9EE2}\x{9EE3}\x{9EE4}\x{9EE5}' - . '\x{9EE6}\x{9EE7}\x{9EE8}\x{9EE9}\x{9EEA}\x{9EEB}\x{9EED}\x{9EEE}\x{9EEF}' - . '\x{9EF0}\x{9EF2}\x{9EF3}\x{9EF4}\x{9EF5}\x{9EF6}\x{9EF7}\x{9EF8}\x{9EF9}' - . '\x{9EFA}\x{9EFB}\x{9EFC}\x{9EFD}\x{9EFE}\x{9EFF}\x{9F00}\x{9F01}\x{9F02}' - . '\x{9F04}\x{9F05}\x{9F06}\x{9F07}\x{9F08}\x{9F09}\x{9F0A}\x{9F0B}\x{9F0C}' - . '\x{9F0D}\x{9F0E}\x{9F0F}\x{9F10}\x{9F12}\x{9F13}\x{9F15}\x{9F16}\x{9F17}' - . '\x{9F18}\x{9F19}\x{9F1A}\x{9F1B}\x{9F1C}\x{9F1D}\x{9F1E}\x{9F1F}\x{9F20}' - . '\x{9F22}\x{9F23}\x{9F24}\x{9F25}\x{9F27}\x{9F28}\x{9F29}\x{9F2A}\x{9F2B}' - . '\x{9F2C}\x{9F2D}\x{9F2E}\x{9F2F}\x{9F30}\x{9F31}\x{9F32}\x{9F33}\x{9F34}' - . '\x{9F35}\x{9F36}\x{9F37}\x{9F38}\x{9F39}\x{9F3A}\x{9F3B}\x{9F3C}\x{9F3D}' - . '\x{9F3E}\x{9F3F}\x{9F40}\x{9F41}\x{9F42}\x{9F43}\x{9F44}\x{9F46}\x{9F47}' - . '\x{9F48}\x{9F49}\x{9F4A}\x{9F4B}\x{9F4C}\x{9F4D}\x{9F4E}\x{9F4F}\x{9F50}' - . '\x{9F51}\x{9F52}\x{9F54}\x{9F55}\x{9F56}\x{9F57}\x{9F58}\x{9F59}\x{9F5A}' - . '\x{9F5B}\x{9F5C}\x{9F5D}\x{9F5E}\x{9F5F}\x{9F60}\x{9F61}\x{9F63}\x{9F64}' - . '\x{9F65}\x{9F66}\x{9F67}\x{9F68}\x{9F69}\x{9F6A}\x{9F6B}\x{9F6C}\x{9F6E}' - . '\x{9F6F}\x{9F70}\x{9F71}\x{9F72}\x{9F73}\x{9F74}\x{9F75}\x{9F76}\x{9F77}' - . '\x{9F78}\x{9F79}\x{9F7A}\x{9F7B}\x{9F7C}\x{9F7D}\x{9F7E}\x{9F7F}\x{9F80}' - . '\x{9F81}\x{9F82}\x{9F83}\x{9F84}\x{9F85}\x{9F86}\x{9F87}\x{9F88}\x{9F89}' - . '\x{9F8A}\x{9F8B}\x{9F8C}\x{9F8D}\x{9F8E}\x{9F8F}\x{9F90}\x{9F91}\x{9F92}' - . '\x{9F93}\x{9F94}\x{9F95}\x{9F96}\x{9F97}\x{9F98}\x{9F99}\x{9F9A}\x{9F9B}' - . '\x{9F9C}\x{9F9D}\x{9F9E}\x{9F9F}\x{9FA0}\x{9FA2}\x{9FA4}\x{9FA5}]{1,20}$/iu', -]; diff --git a/lib/laminas/laminas-validator/src/Hostname/Com.php b/lib/laminas/laminas-validator/src/Hostname/Com.php deleted file mode 100644 index 5db58df61..000000000 --- a/lib/laminas/laminas-validator/src/Hostname/Com.php +++ /dev/null @@ -1,176 +0,0 @@ - '/^[\x{002d}0-9\x{0400}-\x{052f}]{1,63}$/iu', - 2 => '/^[\x{002d}0-9\x{0370}-\x{03ff}]{1,63}$/iu', - 3 => '/^[\x{002d}0-9a-z\x{ac00}-\x{d7a3}]{1,17}$/iu', - // @codingStandardsIgnoreStart - 4 => '/^[\x{002d}0-9a-z·à-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž]{1,63}$/iu', - // @codingStandardsIgnoreEnd - 5 => '/^[\x{002d}0-9A-Za-z\x{3400}-\x{3401}\x{3404}-\x{3406}\x{340C}\x{3416}\x{341C}' -. '\x{3421}\x{3424}\x{3428}-\x{3429}\x{342B}-\x{342E}\x{3430}-\x{3434}\x{3436}' -. '\x{3438}-\x{343C}\x{343E}\x{3441}-\x{3445}\x{3447}\x{3449}-\x{3451}\x{3453}' -. '\x{3457}-\x{345F}\x{3463}-\x{3467}\x{346E}-\x{3471}\x{3473}-\x{3477}\x{3479}-\x{348E}\x{3491}-\x{3497}' -. '\x{3499}-\x{34A1}\x{34A4}-\x{34AD}\x{34AF}-\x{34B0}\x{34B2}-\x{34BF}\x{34C2}-\x{34C5}\x{34C7}-\x{34CC}' -. '\x{34CE}-\x{34D1}\x{34D3}-\x{34D8}\x{34DA}-\x{34E4}\x{34E7}-\x{34E9}\x{34EC}-\x{34EF}\x{34F1}-\x{34FE}' -. '\x{3500}-\x{3507}\x{350A}-\x{3513}\x{3515}\x{3517}-\x{351A}\x{351C}-\x{351E}\x{3520}-\x{352A}' -. '\x{352C}-\x{3552}\x{3554}-\x{355C}\x{355E}-\x{3567}\x{3569}-\x{3573}\x{3575}-\x{357C}\x{3580}-\x{3588}' -. '\x{358F}-\x{3598}\x{359E}-\x{35AB}\x{35B4}-\x{35CD}\x{35D0}\x{35D3}-\x{35DC}\x{35E2}-\x{35ED}' -. '\x{35F0}-\x{35F6}\x{35FB}-\x{3602}\x{3605}-\x{360E}\x{3610}-\x{3611}\x{3613}-\x{3616}\x{3619}-\x{362D}' -. '\x{362F}-\x{3634}\x{3636}-\x{363B}\x{363F}-\x{3645}\x{3647}-\x{364B}\x{364D}-\x{3653}\x{3655}' -. '\x{3659}-\x{365E}\x{3660}-\x{3665}\x{3667}-\x{367C}\x{367E}\x{3680}-\x{3685}\x{3687}' -. '\x{3689}-\x{3690}\x{3692}-\x{3698}\x{369A}\x{369C}-\x{36AE}\x{36B0}-\x{36BF}\x{36C1}-\x{36C5}' -. '\x{36C9}-\x{36CA}\x{36CD}-\x{36DE}\x{36E1}-\x{36E2}\x{36E5}-\x{36FE}\x{3701}-\x{3713}\x{3715}-\x{371E}' -. '\x{3720}-\x{372C}\x{372E}-\x{3745}\x{3747}-\x{3748}\x{374A}\x{374C}-\x{3759}\x{375B}-\x{3760}' -. '\x{3762}-\x{3767}\x{3769}-\x{3772}\x{3774}-\x{378C}\x{378F}-\x{379C}\x{379F}\x{37A1}-\x{37AD}' -. '\x{37AF}-\x{37B7}\x{37B9}-\x{37C1}\x{37C3}-\x{37C5}\x{37C7}-\x{37D4}\x{37D6}-\x{37E0}\x{37E2}' -. '\x{37E5}-\x{37ED}\x{37EF}-\x{37F6}\x{37F8}-\x{3802}\x{3804}-\x{381D}\x{3820}-\x{3822}\x{3825}-\x{382A}' -. '\x{382D}-\x{382F}\x{3831}-\x{3832}\x{3834}-\x{384C}\x{384E}-\x{3860}\x{3862}-\x{3863}\x{3865}-\x{386B}' -. '\x{386D}-\x{3886}\x{3888}-\x{38A1}\x{38A3}\x{38A5}-\x{38AA}\x{38AC}\x{38AE}-\x{38B0}' -. '\x{38B2}-\x{38B6}\x{38B8}\x{38BA}-\x{38BE}\x{38C0}-\x{38C9}\x{38CB}-\x{38D4}\x{38D8}-\x{38E0}' -. '\x{38E2}-\x{38E6}\x{38EB}-\x{38ED}\x{38EF}-\x{38F2}\x{38F5}-\x{38F7}\x{38FA}-\x{38FF}\x{3901}-\x{392A}' -. '\x{392C}\x{392E}-\x{393B}\x{393E}-\x{3956}\x{395A}-\x{3969}\x{396B}-\x{397A}\x{397C}-\x{3987}' -. '\x{3989}-\x{3998}\x{399A}-\x{39B0}\x{39B2}\x{39B4}-\x{39D0}\x{39D2}-\x{39DA}\x{39DE}-\x{39DF}' -. '\x{39E1}-\x{39EF}\x{39F1}-\x{3A17}\x{3A19}-\x{3A2A}\x{3A2D}-\x{3A40}\x{3A43}-\x{3A4E}\x{3A50}' -. '\x{3A52}-\x{3A5E}\x{3A60}-\x{3A6D}\x{3A6F}-\x{3A77}\x{3A79}-\x{3A82}\x{3A84}-\x{3A85}\x{3A87}-\x{3A89}' -. '\x{3A8B}-\x{3A8F}\x{3A91}-\x{3A93}\x{3A95}-\x{3A96}\x{3A9A}\x{3A9C}-\x{3AA6}\x{3AA8}-\x{3AA9}' -. '\x{3AAB}-\x{3AB1}\x{3AB4}-\x{3ABC}\x{3ABE}-\x{3AC5}\x{3ACA}-\x{3ACB}\x{3ACD}-\x{3AD5}\x{3AD7}-\x{3AE1}' -. '\x{3AE4}-\x{3AE7}\x{3AE9}-\x{3AEC}\x{3AEE}-\x{3AFD}\x{3B01}-\x{3B10}\x{3B12}-\x{3B15}\x{3B17}-\x{3B1E}' -. '\x{3B20}-\x{3B23}\x{3B25}-\x{3B27}\x{3B29}-\x{3B36}\x{3B38}-\x{3B39}\x{3B3B}-\x{3B3C}\x{3B3F}' -. '\x{3B41}-\x{3B44}\x{3B47}-\x{3B4C}\x{3B4E}\x{3B51}-\x{3B55}\x{3B58}-\x{3B62}\x{3B68}-\x{3B72}' -. '\x{3B78}-\x{3B88}\x{3B8B}-\x{3B9F}\x{3BA1}\x{3BA3}-\x{3BBA}\x{3BBC}\x{3BBF}-\x{3BD0}' -. '\x{3BD3}-\x{3BE6}\x{3BEA}-\x{3BFB}\x{3BFE}-\x{3C12}\x{3C14}-\x{3C1B}\x{3C1D}-\x{3C37}\x{3C39}-\x{3C4F}' -. '\x{3C52}\x{3C54}-\x{3C5C}\x{3C5E}-\x{3C68}\x{3C6A}-\x{3C76}\x{3C78}-\x{3C8F}\x{3C91}-\x{3CA8}' -. '\x{3CAA}-\x{3CAD}\x{3CAF}-\x{3CBE}\x{3CC0}-\x{3CC8}\x{3CCA}-\x{3CD3}\x{3CD6}-\x{3CE0}\x{3CE4}-\x{3CEE}' -. '\x{3CF3}-\x{3D0A}\x{3D0E}-\x{3D1E}\x{3D20}-\x{3D21}\x{3D25}-\x{3D38}\x{3D3B}-\x{3D46}\x{3D4A}-\x{3D59}' -. '\x{3D5D}-\x{3D7B}\x{3D7D}-\x{3D81}\x{3D84}-\x{3D88}\x{3D8C}-\x{3D8F}\x{3D91}-\x{3D98}\x{3D9A}-\x{3D9C}' -. '\x{3D9E}-\x{3DA1}\x{3DA3}-\x{3DB0}\x{3DB2}-\x{3DB5}\x{3DB9}-\x{3DBC}\x{3DBE}-\x{3DCB}\x{3DCD}-\x{3DDB}' -. '\x{3DDF}-\x{3DE8}\x{3DEB}-\x{3DF0}\x{3DF3}-\x{3DF9}\x{3DFB}-\x{3DFC}\x{3DFE}-\x{3E05}\x{3E08}-\x{3E33}' -. '\x{3E35}-\x{3E3E}\x{3E40}-\x{3E47}\x{3E49}-\x{3E67}\x{3E6B}-\x{3E6F}\x{3E71}-\x{3E85}\x{3E87}-\x{3E8C}' -. '\x{3E8E}-\x{3E98}\x{3E9A}-\x{3EA1}\x{3EA3}-\x{3EAE}\x{3EB0}-\x{3EB5}\x{3EB7}-\x{3EBA}\x{3EBD}' -. '\x{3EBF}-\x{3EC4}\x{3EC7}-\x{3ECE}\x{3ED1}-\x{3ED7}\x{3ED9}-\x{3EDA}\x{3EDD}-\x{3EE3}\x{3EE7}-\x{3EE8}' -. '\x{3EEB}-\x{3EF2}\x{3EF5}-\x{3EFF}\x{3F01}-\x{3F02}\x{3F04}-\x{3F07}\x{3F09}-\x{3F44}\x{3F46}-\x{3F4E}' -. '\x{3F50}-\x{3F53}\x{3F55}-\x{3F72}\x{3F74}-\x{3F75}\x{3F77}-\x{3F7B}\x{3F7D}-\x{3FB0}\x{3FB6}-\x{3FBF}' -. '\x{3FC1}-\x{3FCF}\x{3FD1}-\x{3FD3}\x{3FD5}-\x{3FDF}\x{3FE1}-\x{400B}\x{400D}-\x{401C}\x{401E}-\x{4024}' -. '\x{4027}-\x{403F}\x{4041}-\x{4060}\x{4062}-\x{4069}\x{406B}-\x{408A}\x{408C}-\x{40A7}\x{40A9}-\x{40B4}' -. '\x{40B6}-\x{40C2}\x{40C7}-\x{40CF}\x{40D1}-\x{40DE}\x{40E0}-\x{40E7}\x{40E9}-\x{40EE}\x{40F0}-\x{40FB}' -. '\x{40FD}-\x{4109}\x{410B}-\x{4115}\x{4118}-\x{411D}\x{411F}-\x{4122}\x{4124}-\x{4133}\x{4136}-\x{4138}' -. '\x{413A}-\x{4148}\x{414A}-\x{4169}\x{416C}-\x{4185}\x{4188}-\x{418B}\x{418D}-\x{41AD}\x{41AF}-\x{41B3}' -. '\x{41B5}-\x{41C3}\x{41C5}-\x{41C9}\x{41CB}-\x{41F2}\x{41F5}-\x{41FE}\x{4200}-\x{4227}\x{422A}-\x{4246}' -. '\x{4248}-\x{4263}\x{4265}-\x{428B}\x{428D}-\x{42A1}\x{42A3}-\x{42C4}\x{42C8}-\x{42DC}\x{42DE}-\x{430A}' -. '\x{430C}-\x{4335}\x{4337}\x{4342}-\x{435F}\x{4361}-\x{439A}\x{439C}-\x{439D}\x{439F}-\x{43A4}' -. '\x{43A6}-\x{43EC}\x{43EF}-\x{4405}\x{4407}-\x{4429}\x{442B}-\x{4455}\x{4457}-\x{4468}\x{446A}-\x{446D}' -. '\x{446F}-\x{4476}\x{4479}-\x{447D}\x{447F}-\x{4486}\x{4488}-\x{4490}\x{4492}-\x{4498}\x{449A}-\x{44AD}' -. '\x{44B0}-\x{44BD}\x{44C1}-\x{44D3}\x{44D6}-\x{44E7}\x{44EA}\x{44EC}-\x{44FA}\x{44FC}-\x{4541}' -. '\x{4543}-\x{454F}\x{4551}-\x{4562}\x{4564}-\x{4575}\x{4577}-\x{45AB}\x{45AD}-\x{45BD}\x{45BF}-\x{45D5}' -. '\x{45D7}-\x{45EC}\x{45EE}-\x{45F2}\x{45F4}-\x{45FA}\x{45FC}-\x{461A}\x{461C}-\x{461D}\x{461F}-\x{4631}' -. '\x{4633}-\x{4649}\x{464C}\x{464E}-\x{4652}\x{4654}-\x{466A}\x{466C}-\x{4675}\x{4677}-\x{467A}' -. '\x{467C}-\x{4694}\x{4696}-\x{46A3}\x{46A5}-\x{46AB}\x{46AD}-\x{46D2}\x{46D4}-\x{4723}\x{4729}-\x{4732}' -. '\x{4734}-\x{4758}\x{475A}\x{475C}-\x{478B}\x{478D}\x{4791}-\x{47B1}\x{47B3}-\x{47F1}' -. '\x{47F3}-\x{480B}\x{480D}-\x{4815}\x{4817}-\x{4839}\x{483B}-\x{4870}\x{4872}-\x{487A}\x{487C}-\x{487F}' -. '\x{4883}-\x{488E}\x{4890}-\x{4896}\x{4899}-\x{48A2}\x{48A4}-\x{48B9}\x{48BB}-\x{48C8}\x{48CA}-\x{48D1}' -. '\x{48D3}-\x{48E5}\x{48E7}-\x{48F2}\x{48F4}-\x{48FF}\x{4901}-\x{4922}\x{4924}-\x{4928}\x{492A}-\x{4931}' -. '\x{4933}-\x{495B}\x{495D}-\x{4978}\x{497A}\x{497D}\x{4982}-\x{4983}\x{4985}-\x{49A8}' -. '\x{49AA}-\x{49AF}\x{49B1}-\x{49B7}\x{49B9}-\x{49BD}\x{49C1}-\x{49C7}\x{49C9}-\x{49CE}\x{49D0}-\x{49E8}' -. '\x{49EA}\x{49EC}\x{49EE}-\x{4A19}\x{4A1B}-\x{4A43}\x{4A45}-\x{4A4D}\x{4A4F}-\x{4A9E}' -. '\x{4AA0}-\x{4AA9}\x{4AAB}-\x{4B4E}\x{4B50}-\x{4B5B}\x{4B5D}-\x{4B69}\x{4B6B}-\x{4BC2}\x{4BC6}-\x{4BE8}' -. '\x{4BEA}-\x{4BFA}\x{4BFC}-\x{4C06}\x{4C08}-\x{4C2D}\x{4C2F}-\x{4C32}\x{4C34}-\x{4C35}\x{4C37}-\x{4C69}' -. '\x{4C6B}-\x{4C73}\x{4C75}-\x{4C86}\x{4C88}-\x{4C97}\x{4C99}-\x{4C9C}\x{4C9F}-\x{4CA3}\x{4CA5}-\x{4CB5}' -. '\x{4CB7}-\x{4CF8}\x{4CFA}-\x{4D27}\x{4D29}-\x{4DAC}\x{4DAE}-\x{4DB1}\x{4DB3}-\x{4DB5}\x{4E00}-\x{4E54}' -. '\x{4E56}-\x{4E89}\x{4E8B}-\x{4EEC}\x{4EEE}-\x{4FAC}\x{4FAE}-\x{503C}\x{503E}-\x{51E5}\x{51E7}-\x{5270}' -. '\x{5272}-\x{56A1}\x{56A3}-\x{5840}\x{5842}-\x{58B5}\x{58B7}-\x{58CB}\x{58CD}-\x{5BC8}\x{5BCA}-\x{5C01}' -. '\x{5C03}-\x{5C25}\x{5C27}-\x{5D5B}\x{5D5D}-\x{5F08}\x{5F0A}-\x{61F3}\x{61F5}-\x{63BA}\x{63BC}-\x{6441}' -. '\x{6443}-\x{657C}\x{657E}-\x{663E}\x{6640}-\x{66FC}\x{66FE}-\x{6728}\x{672A}-\x{6766}\x{6768}-\x{67A8}' -. '\x{67AA}-\x{685B}\x{685D}-\x{685E}\x{6860}-\x{68B9}\x{68BB}-\x{6AC8}\x{6ACA}-\x{6BB0}\x{6BB2}-\x{6C16}' -. '\x{6C18}-\x{6D9B}\x{6D9D}-\x{6E12}\x{6E14}-\x{6E8B}\x{6E8D}-\x{704D}\x{704F}-\x{7113}\x{7115}-\x{713B}' -. '\x{713D}-\x{7154}\x{7156}-\x{729F}\x{72A1}-\x{731E}\x{7320}-\x{7362}\x{7364}-\x{7533}\x{7535}-\x{7551}' -. '\x{7553}-\x{7572}\x{7574}-\x{75E8}\x{75EA}-\x{7679}\x{767B}-\x{783E}\x{7840}-\x{7A62}\x{7A64}-\x{7AC2}' -. '\x{7AC4}-\x{7B06}\x{7B08}-\x{7B79}\x{7B7B}-\x{7BCE}\x{7BD0}-\x{7D99}\x{7D9B}-\x{7E49}\x{7E4C}-\x{8132}' -. '\x{8134}\x{8136}-\x{81D2}\x{81D4}-\x{8216}\x{8218}-\x{822D}\x{822F}-\x{83B4}\x{83B6}-\x{841F}' -. '\x{8421}-\x{86CC}\x{86CE}-\x{874A}\x{874C}-\x{877E}\x{8780}-\x{8A32}\x{8A34}-\x{8B71}\x{8B73}-\x{8B8E}' -. '\x{8B90}-\x{8DE4}\x{8DE6}-\x{8E9A}\x{8E9C}-\x{8EE1}\x{8EE4}-\x{8F0B}\x{8F0D}-\x{8FB9}\x{8FBB}-\x{9038}' -. '\x{903A}-\x{9196}\x{9198}-\x{91A3}\x{91A5}-\x{91B7}\x{91B9}-\x{91C7}\x{91C9}-\x{91E0}\x{91E2}-\x{91FB}' -. '\x{91FD}-\x{922B}\x{922D}-\x{9270}\x{9272}-\x{9420}\x{9422}-\x{9664}\x{9666}-\x{9679}\x{967B}-\x{9770}' -. '\x{9772}-\x{982B}\x{982D}-\x{98ED}\x{98EF}-\x{99C4}\x{99C6}-\x{9A11}\x{9A14}-\x{9A27}\x{9A29}-\x{9D0D}' -. '\x{9D0F}-\x{9D2B}\x{9D2D}-\x{9D8E}\x{9D90}-\x{9DC5}\x{9DC7}-\x{9E77}\x{9E79}-\x{9EB8}\x{9EBB}-\x{9F20}' -. '\x{9F22}-\x{9F61}\x{9F63}-\x{9FA5}\x{FA28}]{1,20}$/iu', - 6 => '/^[\x{002d}0-9A-Za-z]{1,63}$/iu', - 7 => '/^[\x{00A1}-\x{00FF}]{1,63}$/iu', - 8 => '/^[\x{0100}-\x{017f}]{1,63}$/iu', - 9 => '/^[\x{0180}-\x{024f}]{1,63}$/iu', - 10 => '/^[\x{0250}-\x{02af}]{1,63}$/iu', - 11 => '/^[\x{02b0}-\x{02ff}]{1,63}$/iu', - 12 => '/^[\x{0300}-\x{036f}]{1,63}$/iu', - 13 => '/^[\x{0370}-\x{03ff}]{1,63}$/iu', - 14 => '/^[\x{0400}-\x{04ff}]{1,63}$/iu', - 15 => '/^[\x{0500}-\x{052f}]{1,63}$/iu', - 16 => '/^[\x{0530}-\x{058F}]{1,63}$/iu', - 17 => '/^[\x{0590}-\x{05FF}]{1,63}$/iu', - 18 => '/^[\x{0600}-\x{06FF}]{1,63}$/iu', - 19 => '/^[\x{0700}-\x{074F}]{1,63}$/iu', - 20 => '/^[\x{0780}-\x{07BF}]{1,63}$/iu', - 21 => '/^[\x{0900}-\x{097F}]{1,63}$/iu', - 22 => '/^[\x{0980}-\x{09FF}]{1,63}$/iu', - 23 => '/^[\x{0A00}-\x{0A7F}]{1,63}$/iu', - 24 => '/^[\x{0A80}-\x{0AFF}]{1,63}$/iu', - 25 => '/^[\x{0B00}-\x{0B7F}]{1,63}$/iu', - 26 => '/^[\x{0B80}-\x{0BFF}]{1,63}$/iu', - 27 => '/^[\x{0C00}-\x{0C7F}]{1,63}$/iu', - 28 => '/^[\x{0C80}-\x{0CFF}]{1,63}$/iu', - 29 => '/^[\x{0D00}-\x{0D7F}]{1,63}$/iu', - 30 => '/^[\x{0D80}-\x{0DFF}]{1,63}$/iu', - 31 => '/^[\x{0E00}-\x{0E7F}]{1,63}$/iu', - 32 => '/^[\x{0E80}-\x{0EFF}]{1,63}$/iu', - 33 => '/^[\x{0F00}-\x{0FFF}]{1,63}$/iu', - 34 => '/^[\x{1000}-\x{109F}]{1,63}$/iu', - 35 => '/^[\x{10A0}-\x{10FF}]{1,63}$/iu', - 36 => '/^[\x{1100}-\x{11FF}]{1,63}$/iu', - 37 => '/^[\x{1200}-\x{137F}]{1,63}$/iu', - 38 => '/^[\x{13A0}-\x{13FF}]{1,63}$/iu', - 39 => '/^[\x{1400}-\x{167F}]{1,63}$/iu', - 40 => '/^[\x{1680}-\x{169F}]{1,63}$/iu', - 41 => '/^[\x{16A0}-\x{16FF}]{1,63}$/iu', - 42 => '/^[\x{1700}-\x{171F}]{1,63}$/iu', - 43 => '/^[\x{1720}-\x{173F}]{1,63}$/iu', - 44 => '/^[\x{1740}-\x{175F}]{1,63}$/iu', - 45 => '/^[\x{1760}-\x{177F}]{1,63}$/iu', - 46 => '/^[\x{1780}-\x{17FF}]{1,63}$/iu', - 47 => '/^[\x{1800}-\x{18AF}]{1,63}$/iu', - 48 => '/^[\x{1E00}-\x{1EFF}]{1,63}$/iu', - 49 => '/^[\x{1F00}-\x{1FFF}]{1,63}$/iu', - 50 => '/^[\x{2070}-\x{209F}]{1,63}$/iu', - 51 => '/^[\x{2100}-\x{214F}]{1,63}$/iu', - 52 => '/^[\x{2150}-\x{218F}]{1,63}$/iu', - 53 => '/^[\x{2460}-\x{24FF}]{1,63}$/iu', - 54 => '/^[\x{2E80}-\x{2EFF}]{1,63}$/iu', - 55 => '/^[\x{2F00}-\x{2FDF}]{1,63}$/iu', - 56 => '/^[\x{2FF0}-\x{2FFF}]{1,63}$/iu', - 57 => '/^[\x{3040}-\x{309F}]{1,63}$/iu', - 58 => '/^[\x{30A0}-\x{30FF}]{1,63}$/iu', - 59 => '/^[\x{3100}-\x{312F}]{1,63}$/iu', - 60 => '/^[\x{3130}-\x{318F}]{1,63}$/iu', - 61 => '/^[\x{3190}-\x{319F}]{1,63}$/iu', - 62 => '/^[\x{31A0}-\x{31BF}]{1,63}$/iu', - 63 => '/^[\x{31F0}-\x{31FF}]{1,63}$/iu', - 64 => '/^[\x{3200}-\x{32FF}]{1,63}$/iu', - 65 => '/^[\x{3300}-\x{33FF}]{1,63}$/iu', - 66 => '/^[\x{3400}-\x{4DBF}]{1,63}$/iu', - 67 => '/^[\x{4E00}-\x{9FFF}]{1,63}$/iu', - 68 => '/^[\x{A000}-\x{A48F}]{1,63}$/iu', - 69 => '/^[\x{A490}-\x{A4CF}]{1,63}$/iu', - 70 => '/^[\x{AC00}-\x{D7AF}]{1,63}$/iu', - 73 => '/^[\x{F900}-\x{FAFF}]{1,63}$/iu', - 74 => '/^[\x{FB00}-\x{FB4F}]{1,63}$/iu', - 75 => '/^[\x{FB50}-\x{FDFF}]{1,63}$/iu', - 76 => '/^[\x{FE20}-\x{FE2F}]{1,63}$/iu', - 77 => '/^[\x{FE70}-\x{FEFF}]{1,63}$/iu', - 78 => '/^[\x{FF00}-\x{FFEF}]{1,63}$/iu', - 79 => '/^[\x{20000}-\x{2A6DF}]{1,63}$/iu', - 80 => '/^[\x{2F800}-\x{2FA1F}]{1,63}$/iu', -]; diff --git a/lib/laminas/laminas-validator/src/Hostname/Jp.php b/lib/laminas/laminas-validator/src/Hostname/Jp.php deleted file mode 100644 index 8520f6a1d..000000000 --- a/lib/laminas/laminas-validator/src/Hostname/Jp.php +++ /dev/null @@ -1,719 +0,0 @@ - '/^[\x{002d}0-9a-z\x{3005}-\x{3007}\x{3041}-\x{3093}\x{309D}\x{309E}' - . '\x{30A1}-\x{30F6}\x{30FC}' - . '\x{30FD}\x{30FE}\x{4E00}\x{4E01}\x{4E03}\x{4E07}\x{4E08}\x{4E09}\x{4E0A}' - . '\x{4E0B}\x{4E0D}\x{4E0E}\x{4E10}\x{4E11}\x{4E14}\x{4E15}\x{4E16}\x{4E17}' - . '\x{4E18}\x{4E19}\x{4E1E}\x{4E21}\x{4E26}\x{4E2A}\x{4E2D}\x{4E31}\x{4E32}' - . '\x{4E36}\x{4E38}\x{4E39}\x{4E3B}\x{4E3C}\x{4E3F}\x{4E42}\x{4E43}\x{4E45}' - . '\x{4E4B}\x{4E4D}\x{4E4E}\x{4E4F}\x{4E55}\x{4E56}\x{4E57}\x{4E58}\x{4E59}' - . '\x{4E5D}\x{4E5E}\x{4E5F}\x{4E62}\x{4E71}\x{4E73}\x{4E7E}\x{4E80}\x{4E82}' - . '\x{4E85}\x{4E86}\x{4E88}\x{4E89}\x{4E8A}\x{4E8B}\x{4E8C}\x{4E8E}\x{4E91}' - . '\x{4E92}\x{4E94}\x{4E95}\x{4E98}\x{4E99}\x{4E9B}\x{4E9C}\x{4E9E}\x{4E9F}' - . '\x{4EA0}\x{4EA1}\x{4EA2}\x{4EA4}\x{4EA5}\x{4EA6}\x{4EA8}\x{4EAB}\x{4EAC}' - . '\x{4EAD}\x{4EAE}\x{4EB0}\x{4EB3}\x{4EB6}\x{4EBA}\x{4EC0}\x{4EC1}\x{4EC2}' - . '\x{4EC4}\x{4EC6}\x{4EC7}\x{4ECA}\x{4ECB}\x{4ECD}\x{4ECE}\x{4ECF}\x{4ED4}' - . '\x{4ED5}\x{4ED6}\x{4ED7}\x{4ED8}\x{4ED9}\x{4EDD}\x{4EDE}\x{4EDF}\x{4EE3}' - . '\x{4EE4}\x{4EE5}\x{4EED}\x{4EEE}\x{4EF0}\x{4EF2}\x{4EF6}\x{4EF7}\x{4EFB}' - . '\x{4F01}\x{4F09}\x{4F0A}\x{4F0D}\x{4F0E}\x{4F0F}\x{4F10}\x{4F11}\x{4F1A}' - . '\x{4F1C}\x{4F1D}\x{4F2F}\x{4F30}\x{4F34}\x{4F36}\x{4F38}\x{4F3A}\x{4F3C}' - . '\x{4F3D}\x{4F43}\x{4F46}\x{4F47}\x{4F4D}\x{4F4E}\x{4F4F}\x{4F50}\x{4F51}' - . '\x{4F53}\x{4F55}\x{4F57}\x{4F59}\x{4F5A}\x{4F5B}\x{4F5C}\x{4F5D}\x{4F5E}' - . '\x{4F69}\x{4F6F}\x{4F70}\x{4F73}\x{4F75}\x{4F76}\x{4F7B}\x{4F7C}\x{4F7F}' - . '\x{4F83}\x{4F86}\x{4F88}\x{4F8B}\x{4F8D}\x{4F8F}\x{4F91}\x{4F96}\x{4F98}' - . '\x{4F9B}\x{4F9D}\x{4FA0}\x{4FA1}\x{4FAB}\x{4FAD}\x{4FAE}\x{4FAF}\x{4FB5}' - . '\x{4FB6}\x{4FBF}\x{4FC2}\x{4FC3}\x{4FC4}\x{4FCA}\x{4FCE}\x{4FD0}\x{4FD1}' - . '\x{4FD4}\x{4FD7}\x{4FD8}\x{4FDA}\x{4FDB}\x{4FDD}\x{4FDF}\x{4FE1}\x{4FE3}' - . '\x{4FE4}\x{4FE5}\x{4FEE}\x{4FEF}\x{4FF3}\x{4FF5}\x{4FF6}\x{4FF8}\x{4FFA}' - . '\x{4FFE}\x{5005}\x{5006}\x{5009}\x{500B}\x{500D}\x{500F}\x{5011}\x{5012}' - . '\x{5014}\x{5016}\x{5019}\x{501A}\x{501F}\x{5021}\x{5023}\x{5024}\x{5025}' - . '\x{5026}\x{5028}\x{5029}\x{502A}\x{502B}\x{502C}\x{502D}\x{5036}\x{5039}' - . '\x{5043}\x{5047}\x{5048}\x{5049}\x{504F}\x{5050}\x{5055}\x{5056}\x{505A}' - . '\x{505C}\x{5065}\x{506C}\x{5072}\x{5074}\x{5075}\x{5076}\x{5078}\x{507D}' - . '\x{5080}\x{5085}\x{508D}\x{5091}\x{5098}\x{5099}\x{509A}\x{50AC}\x{50AD}' - . '\x{50B2}\x{50B3}\x{50B4}\x{50B5}\x{50B7}\x{50BE}\x{50C2}\x{50C5}\x{50C9}' - . '\x{50CA}\x{50CD}\x{50CF}\x{50D1}\x{50D5}\x{50D6}\x{50DA}\x{50DE}\x{50E3}' - . '\x{50E5}\x{50E7}\x{50ED}\x{50EE}\x{50F5}\x{50F9}\x{50FB}\x{5100}\x{5101}' - . '\x{5102}\x{5104}\x{5109}\x{5112}\x{5114}\x{5115}\x{5116}\x{5118}\x{511A}' - . '\x{511F}\x{5121}\x{512A}\x{5132}\x{5137}\x{513A}\x{513B}\x{513C}\x{513F}' - . '\x{5140}\x{5141}\x{5143}\x{5144}\x{5145}\x{5146}\x{5147}\x{5148}\x{5149}' - . '\x{514B}\x{514C}\x{514D}\x{514E}\x{5150}\x{5152}\x{5154}\x{515A}\x{515C}' - . '\x{5162}\x{5165}\x{5168}\x{5169}\x{516A}\x{516B}\x{516C}\x{516D}\x{516E}' - . '\x{5171}\x{5175}\x{5176}\x{5177}\x{5178}\x{517C}\x{5180}\x{5182}\x{5185}' - . '\x{5186}\x{5189}\x{518A}\x{518C}\x{518D}\x{518F}\x{5190}\x{5191}\x{5192}' - . '\x{5193}\x{5195}\x{5196}\x{5197}\x{5199}\x{51A0}\x{51A2}\x{51A4}\x{51A5}' - . '\x{51A6}\x{51A8}\x{51A9}\x{51AA}\x{51AB}\x{51AC}\x{51B0}\x{51B1}\x{51B2}' - . '\x{51B3}\x{51B4}\x{51B5}\x{51B6}\x{51B7}\x{51BD}\x{51C4}\x{51C5}\x{51C6}' - . '\x{51C9}\x{51CB}\x{51CC}\x{51CD}\x{51D6}\x{51DB}\x{51DC}\x{51DD}\x{51E0}' - . '\x{51E1}\x{51E6}\x{51E7}\x{51E9}\x{51EA}\x{51ED}\x{51F0}\x{51F1}\x{51F5}' - . '\x{51F6}\x{51F8}\x{51F9}\x{51FA}\x{51FD}\x{51FE}\x{5200}\x{5203}\x{5204}' - . '\x{5206}\x{5207}\x{5208}\x{520A}\x{520B}\x{520E}\x{5211}\x{5214}\x{5217}' - . '\x{521D}\x{5224}\x{5225}\x{5227}\x{5229}\x{522A}\x{522E}\x{5230}\x{5233}' - . '\x{5236}\x{5237}\x{5238}\x{5239}\x{523A}\x{523B}\x{5243}\x{5244}\x{5247}' - . '\x{524A}\x{524B}\x{524C}\x{524D}\x{524F}\x{5254}\x{5256}\x{525B}\x{525E}' - . '\x{5263}\x{5264}\x{5265}\x{5269}\x{526A}\x{526F}\x{5270}\x{5271}\x{5272}' - . '\x{5273}\x{5274}\x{5275}\x{527D}\x{527F}\x{5283}\x{5287}\x{5288}\x{5289}' - . '\x{528D}\x{5291}\x{5292}\x{5294}\x{529B}\x{529F}\x{52A0}\x{52A3}\x{52A9}' - . '\x{52AA}\x{52AB}\x{52AC}\x{52AD}\x{52B1}\x{52B4}\x{52B5}\x{52B9}\x{52BC}' - . '\x{52BE}\x{52C1}\x{52C3}\x{52C5}\x{52C7}\x{52C9}\x{52CD}\x{52D2}\x{52D5}' - . '\x{52D7}\x{52D8}\x{52D9}\x{52DD}\x{52DE}\x{52DF}\x{52E0}\x{52E2}\x{52E3}' - . '\x{52E4}\x{52E6}\x{52E7}\x{52F2}\x{52F3}\x{52F5}\x{52F8}\x{52F9}\x{52FA}' - . '\x{52FE}\x{52FF}\x{5301}\x{5302}\x{5305}\x{5306}\x{5308}\x{530D}\x{530F}' - . '\x{5310}\x{5315}\x{5316}\x{5317}\x{5319}\x{531A}\x{531D}\x{5320}\x{5321}' - . '\x{5323}\x{532A}\x{532F}\x{5331}\x{5333}\x{5338}\x{5339}\x{533A}\x{533B}' - . '\x{533F}\x{5340}\x{5341}\x{5343}\x{5345}\x{5346}\x{5347}\x{5348}\x{5349}' - . '\x{534A}\x{534D}\x{5351}\x{5352}\x{5353}\x{5354}\x{5357}\x{5358}\x{535A}' - . '\x{535C}\x{535E}\x{5360}\x{5366}\x{5369}\x{536E}\x{536F}\x{5370}\x{5371}' - . '\x{5373}\x{5374}\x{5375}\x{5377}\x{5378}\x{537B}\x{537F}\x{5382}\x{5384}' - . '\x{5396}\x{5398}\x{539A}\x{539F}\x{53A0}\x{53A5}\x{53A6}\x{53A8}\x{53A9}' - . '\x{53AD}\x{53AE}\x{53B0}\x{53B3}\x{53B6}\x{53BB}\x{53C2}\x{53C3}\x{53C8}' - . '\x{53C9}\x{53CA}\x{53CB}\x{53CC}\x{53CD}\x{53CE}\x{53D4}\x{53D6}\x{53D7}' - . '\x{53D9}\x{53DB}\x{53DF}\x{53E1}\x{53E2}\x{53E3}\x{53E4}\x{53E5}\x{53E8}' - . '\x{53E9}\x{53EA}\x{53EB}\x{53EC}\x{53ED}\x{53EE}\x{53EF}\x{53F0}\x{53F1}' - . '\x{53F2}\x{53F3}\x{53F6}\x{53F7}\x{53F8}\x{53FA}\x{5401}\x{5403}\x{5404}' - . '\x{5408}\x{5409}\x{540A}\x{540B}\x{540C}\x{540D}\x{540E}\x{540F}\x{5410}' - . '\x{5411}\x{541B}\x{541D}\x{541F}\x{5420}\x{5426}\x{5429}\x{542B}\x{542C}' - . '\x{542D}\x{542E}\x{5436}\x{5438}\x{5439}\x{543B}\x{543C}\x{543D}\x{543E}' - . '\x{5440}\x{5442}\x{5446}\x{5448}\x{5449}\x{544A}\x{544E}\x{5451}\x{545F}' - . '\x{5468}\x{546A}\x{5470}\x{5471}\x{5473}\x{5475}\x{5476}\x{5477}\x{547B}' - . '\x{547C}\x{547D}\x{5480}\x{5484}\x{5486}\x{548B}\x{548C}\x{548E}\x{548F}' - . '\x{5490}\x{5492}\x{54A2}\x{54A4}\x{54A5}\x{54A8}\x{54AB}\x{54AC}\x{54AF}' - . '\x{54B2}\x{54B3}\x{54B8}\x{54BC}\x{54BD}\x{54BE}\x{54C0}\x{54C1}\x{54C2}' - . '\x{54C4}\x{54C7}\x{54C8}\x{54C9}\x{54D8}\x{54E1}\x{54E2}\x{54E5}\x{54E6}' - . '\x{54E8}\x{54E9}\x{54ED}\x{54EE}\x{54F2}\x{54FA}\x{54FD}\x{5504}\x{5506}' - . '\x{5507}\x{550F}\x{5510}\x{5514}\x{5516}\x{552E}\x{552F}\x{5531}\x{5533}' - . '\x{5538}\x{5539}\x{553E}\x{5540}\x{5544}\x{5545}\x{5546}\x{554C}\x{554F}' - . '\x{5553}\x{5556}\x{5557}\x{555C}\x{555D}\x{5563}\x{557B}\x{557C}\x{557E}' - . '\x{5580}\x{5583}\x{5584}\x{5587}\x{5589}\x{558A}\x{558B}\x{5598}\x{5599}' - . '\x{559A}\x{559C}\x{559D}\x{559E}\x{559F}\x{55A7}\x{55A8}\x{55A9}\x{55AA}' - . '\x{55AB}\x{55AC}\x{55AE}\x{55B0}\x{55B6}\x{55C4}\x{55C5}\x{55C7}\x{55D4}' - . '\x{55DA}\x{55DC}\x{55DF}\x{55E3}\x{55E4}\x{55F7}\x{55F9}\x{55FD}\x{55FE}' - . '\x{5606}\x{5609}\x{5614}\x{5616}\x{5617}\x{5618}\x{561B}\x{5629}\x{562F}' - . '\x{5631}\x{5632}\x{5634}\x{5636}\x{5638}\x{5642}\x{564C}\x{564E}\x{5650}' - . '\x{565B}\x{5664}\x{5668}\x{566A}\x{566B}\x{566C}\x{5674}\x{5678}\x{567A}' - . '\x{5680}\x{5686}\x{5687}\x{568A}\x{568F}\x{5694}\x{56A0}\x{56A2}\x{56A5}' - . '\x{56AE}\x{56B4}\x{56B6}\x{56BC}\x{56C0}\x{56C1}\x{56C2}\x{56C3}\x{56C8}' - . '\x{56CE}\x{56D1}\x{56D3}\x{56D7}\x{56D8}\x{56DA}\x{56DB}\x{56DE}\x{56E0}' - . '\x{56E3}\x{56EE}\x{56F0}\x{56F2}\x{56F3}\x{56F9}\x{56FA}\x{56FD}\x{56FF}' - . '\x{5700}\x{5703}\x{5704}\x{5708}\x{5709}\x{570B}\x{570D}\x{570F}\x{5712}' - . '\x{5713}\x{5716}\x{5718}\x{571C}\x{571F}\x{5726}\x{5727}\x{5728}\x{572D}' - . '\x{5730}\x{5737}\x{5738}\x{573B}\x{5740}\x{5742}\x{5747}\x{574A}\x{574E}' - . '\x{574F}\x{5750}\x{5751}\x{5761}\x{5764}\x{5766}\x{5769}\x{576A}\x{577F}' - . '\x{5782}\x{5788}\x{5789}\x{578B}\x{5793}\x{57A0}\x{57A2}\x{57A3}\x{57A4}' - . '\x{57AA}\x{57B0}\x{57B3}\x{57C0}\x{57C3}\x{57C6}\x{57CB}\x{57CE}\x{57D2}' - . '\x{57D3}\x{57D4}\x{57D6}\x{57DC}\x{57DF}\x{57E0}\x{57E3}\x{57F4}\x{57F7}' - . '\x{57F9}\x{57FA}\x{57FC}\x{5800}\x{5802}\x{5805}\x{5806}\x{580A}\x{580B}' - . '\x{5815}\x{5819}\x{581D}\x{5821}\x{5824}\x{582A}\x{582F}\x{5830}\x{5831}' - . '\x{5834}\x{5835}\x{583A}\x{583D}\x{5840}\x{5841}\x{584A}\x{584B}\x{5851}' - . '\x{5852}\x{5854}\x{5857}\x{5858}\x{5859}\x{585A}\x{585E}\x{5862}\x{5869}' - . '\x{586B}\x{5870}\x{5872}\x{5875}\x{5879}\x{587E}\x{5883}\x{5885}\x{5893}' - . '\x{5897}\x{589C}\x{589F}\x{58A8}\x{58AB}\x{58AE}\x{58B3}\x{58B8}\x{58B9}' - . '\x{58BA}\x{58BB}\x{58BE}\x{58C1}\x{58C5}\x{58C7}\x{58CA}\x{58CC}\x{58D1}' - . '\x{58D3}\x{58D5}\x{58D7}\x{58D8}\x{58D9}\x{58DC}\x{58DE}\x{58DF}\x{58E4}' - . '\x{58E5}\x{58EB}\x{58EC}\x{58EE}\x{58EF}\x{58F0}\x{58F1}\x{58F2}\x{58F7}' - . '\x{58F9}\x{58FA}\x{58FB}\x{58FC}\x{58FD}\x{5902}\x{5909}\x{590A}\x{590F}' - . '\x{5910}\x{5915}\x{5916}\x{5918}\x{5919}\x{591A}\x{591B}\x{591C}\x{5922}' - . '\x{5925}\x{5927}\x{5929}\x{592A}\x{592B}\x{592C}\x{592D}\x{592E}\x{5931}' - . '\x{5932}\x{5937}\x{5938}\x{593E}\x{5944}\x{5947}\x{5948}\x{5949}\x{594E}' - . '\x{594F}\x{5950}\x{5951}\x{5954}\x{5955}\x{5957}\x{5958}\x{595A}\x{5960}' - . '\x{5962}\x{5965}\x{5967}\x{5968}\x{5969}\x{596A}\x{596C}\x{596E}\x{5973}' - . '\x{5974}\x{5978}\x{597D}\x{5981}\x{5982}\x{5983}\x{5984}\x{598A}\x{598D}' - . '\x{5993}\x{5996}\x{5999}\x{599B}\x{599D}\x{59A3}\x{59A5}\x{59A8}\x{59AC}' - . '\x{59B2}\x{59B9}\x{59BB}\x{59BE}\x{59C6}\x{59C9}\x{59CB}\x{59D0}\x{59D1}' - . '\x{59D3}\x{59D4}\x{59D9}\x{59DA}\x{59DC}\x{59E5}\x{59E6}\x{59E8}\x{59EA}' - . '\x{59EB}\x{59F6}\x{59FB}\x{59FF}\x{5A01}\x{5A03}\x{5A09}\x{5A11}\x{5A18}' - . '\x{5A1A}\x{5A1C}\x{5A1F}\x{5A20}\x{5A25}\x{5A29}\x{5A2F}\x{5A35}\x{5A36}' - . '\x{5A3C}\x{5A40}\x{5A41}\x{5A46}\x{5A49}\x{5A5A}\x{5A62}\x{5A66}\x{5A6A}' - . '\x{5A6C}\x{5A7F}\x{5A92}\x{5A9A}\x{5A9B}\x{5ABC}\x{5ABD}\x{5ABE}\x{5AC1}' - . '\x{5AC2}\x{5AC9}\x{5ACB}\x{5ACC}\x{5AD0}\x{5AD6}\x{5AD7}\x{5AE1}\x{5AE3}' - . '\x{5AE6}\x{5AE9}\x{5AFA}\x{5AFB}\x{5B09}\x{5B0B}\x{5B0C}\x{5B16}\x{5B22}' - . '\x{5B2A}\x{5B2C}\x{5B30}\x{5B32}\x{5B36}\x{5B3E}\x{5B40}\x{5B43}\x{5B45}' - . '\x{5B50}\x{5B51}\x{5B54}\x{5B55}\x{5B57}\x{5B58}\x{5B5A}\x{5B5B}\x{5B5C}' - . '\x{5B5D}\x{5B5F}\x{5B63}\x{5B64}\x{5B65}\x{5B66}\x{5B69}\x{5B6B}\x{5B70}' - . '\x{5B71}\x{5B73}\x{5B75}\x{5B78}\x{5B7A}\x{5B80}\x{5B83}\x{5B85}\x{5B87}' - . '\x{5B88}\x{5B89}\x{5B8B}\x{5B8C}\x{5B8D}\x{5B8F}\x{5B95}\x{5B97}\x{5B98}' - . '\x{5B99}\x{5B9A}\x{5B9B}\x{5B9C}\x{5B9D}\x{5B9F}\x{5BA2}\x{5BA3}\x{5BA4}' - . '\x{5BA5}\x{5BA6}\x{5BAE}\x{5BB0}\x{5BB3}\x{5BB4}\x{5BB5}\x{5BB6}\x{5BB8}' - . '\x{5BB9}\x{5BBF}\x{5BC2}\x{5BC3}\x{5BC4}\x{5BC5}\x{5BC6}\x{5BC7}\x{5BC9}' - . '\x{5BCC}\x{5BD0}\x{5BD2}\x{5BD3}\x{5BD4}\x{5BDB}\x{5BDD}\x{5BDE}\x{5BDF}' - . '\x{5BE1}\x{5BE2}\x{5BE4}\x{5BE5}\x{5BE6}\x{5BE7}\x{5BE8}\x{5BE9}\x{5BEB}' - . '\x{5BEE}\x{5BF0}\x{5BF3}\x{5BF5}\x{5BF6}\x{5BF8}\x{5BFA}\x{5BFE}\x{5BFF}' - . '\x{5C01}\x{5C02}\x{5C04}\x{5C05}\x{5C06}\x{5C07}\x{5C08}\x{5C09}\x{5C0A}' - . '\x{5C0B}\x{5C0D}\x{5C0E}\x{5C0F}\x{5C11}\x{5C13}\x{5C16}\x{5C1A}\x{5C20}' - . '\x{5C22}\x{5C24}\x{5C28}\x{5C2D}\x{5C31}\x{5C38}\x{5C39}\x{5C3A}\x{5C3B}' - . '\x{5C3C}\x{5C3D}\x{5C3E}\x{5C3F}\x{5C40}\x{5C41}\x{5C45}\x{5C46}\x{5C48}' - . '\x{5C4A}\x{5C4B}\x{5C4D}\x{5C4E}\x{5C4F}\x{5C50}\x{5C51}\x{5C53}\x{5C55}' - . '\x{5C5E}\x{5C60}\x{5C61}\x{5C64}\x{5C65}\x{5C6C}\x{5C6E}\x{5C6F}\x{5C71}' - . '\x{5C76}\x{5C79}\x{5C8C}\x{5C90}\x{5C91}\x{5C94}\x{5CA1}\x{5CA8}\x{5CA9}' - . '\x{5CAB}\x{5CAC}\x{5CB1}\x{5CB3}\x{5CB6}\x{5CB7}\x{5CB8}\x{5CBB}\x{5CBC}' - . '\x{5CBE}\x{5CC5}\x{5CC7}\x{5CD9}\x{5CE0}\x{5CE1}\x{5CE8}\x{5CE9}\x{5CEA}' - . '\x{5CED}\x{5CEF}\x{5CF0}\x{5CF6}\x{5CFA}\x{5CFB}\x{5CFD}\x{5D07}\x{5D0B}' - . '\x{5D0E}\x{5D11}\x{5D14}\x{5D15}\x{5D16}\x{5D17}\x{5D18}\x{5D19}\x{5D1A}' - . '\x{5D1B}\x{5D1F}\x{5D22}\x{5D29}\x{5D4B}\x{5D4C}\x{5D4E}\x{5D50}\x{5D52}' - . '\x{5D5C}\x{5D69}\x{5D6C}\x{5D6F}\x{5D73}\x{5D76}\x{5D82}\x{5D84}\x{5D87}' - . '\x{5D8B}\x{5D8C}\x{5D90}\x{5D9D}\x{5DA2}\x{5DAC}\x{5DAE}\x{5DB7}\x{5DBA}' - . '\x{5DBC}\x{5DBD}\x{5DC9}\x{5DCC}\x{5DCD}\x{5DD2}\x{5DD3}\x{5DD6}\x{5DDB}' - . '\x{5DDD}\x{5DDE}\x{5DE1}\x{5DE3}\x{5DE5}\x{5DE6}\x{5DE7}\x{5DE8}\x{5DEB}' - . '\x{5DEE}\x{5DF1}\x{5DF2}\x{5DF3}\x{5DF4}\x{5DF5}\x{5DF7}\x{5DFB}\x{5DFD}' - . '\x{5DFE}\x{5E02}\x{5E03}\x{5E06}\x{5E0B}\x{5E0C}\x{5E11}\x{5E16}\x{5E19}' - . '\x{5E1A}\x{5E1B}\x{5E1D}\x{5E25}\x{5E2B}\x{5E2D}\x{5E2F}\x{5E30}\x{5E33}' - . '\x{5E36}\x{5E37}\x{5E38}\x{5E3D}\x{5E40}\x{5E43}\x{5E44}\x{5E45}\x{5E47}' - . '\x{5E4C}\x{5E4E}\x{5E54}\x{5E55}\x{5E57}\x{5E5F}\x{5E61}\x{5E62}\x{5E63}' - . '\x{5E64}\x{5E72}\x{5E73}\x{5E74}\x{5E75}\x{5E76}\x{5E78}\x{5E79}\x{5E7A}' - . '\x{5E7B}\x{5E7C}\x{5E7D}\x{5E7E}\x{5E7F}\x{5E81}\x{5E83}\x{5E84}\x{5E87}' - . '\x{5E8A}\x{5E8F}\x{5E95}\x{5E96}\x{5E97}\x{5E9A}\x{5E9C}\x{5EA0}\x{5EA6}' - . '\x{5EA7}\x{5EAB}\x{5EAD}\x{5EB5}\x{5EB6}\x{5EB7}\x{5EB8}\x{5EC1}\x{5EC2}' - . '\x{5EC3}\x{5EC8}\x{5EC9}\x{5ECA}\x{5ECF}\x{5ED0}\x{5ED3}\x{5ED6}\x{5EDA}' - . '\x{5EDB}\x{5EDD}\x{5EDF}\x{5EE0}\x{5EE1}\x{5EE2}\x{5EE3}\x{5EE8}\x{5EE9}' - . '\x{5EEC}\x{5EF0}\x{5EF1}\x{5EF3}\x{5EF4}\x{5EF6}\x{5EF7}\x{5EF8}\x{5EFA}' - . '\x{5EFB}\x{5EFC}\x{5EFE}\x{5EFF}\x{5F01}\x{5F03}\x{5F04}\x{5F09}\x{5F0A}' - . '\x{5F0B}\x{5F0C}\x{5F0D}\x{5F0F}\x{5F10}\x{5F11}\x{5F13}\x{5F14}\x{5F15}' - . '\x{5F16}\x{5F17}\x{5F18}\x{5F1B}\x{5F1F}\x{5F25}\x{5F26}\x{5F27}\x{5F29}' - . '\x{5F2D}\x{5F2F}\x{5F31}\x{5F35}\x{5F37}\x{5F38}\x{5F3C}\x{5F3E}\x{5F41}' - . '\x{5F48}\x{5F4A}\x{5F4C}\x{5F4E}\x{5F51}\x{5F53}\x{5F56}\x{5F57}\x{5F59}' - . '\x{5F5C}\x{5F5D}\x{5F61}\x{5F62}\x{5F66}\x{5F69}\x{5F6A}\x{5F6B}\x{5F6C}' - . '\x{5F6D}\x{5F70}\x{5F71}\x{5F73}\x{5F77}\x{5F79}\x{5F7C}\x{5F7F}\x{5F80}' - . '\x{5F81}\x{5F82}\x{5F83}\x{5F84}\x{5F85}\x{5F87}\x{5F88}\x{5F8A}\x{5F8B}' - . '\x{5F8C}\x{5F90}\x{5F91}\x{5F92}\x{5F93}\x{5F97}\x{5F98}\x{5F99}\x{5F9E}' - . '\x{5FA0}\x{5FA1}\x{5FA8}\x{5FA9}\x{5FAA}\x{5FAD}\x{5FAE}\x{5FB3}\x{5FB4}' - . '\x{5FB9}\x{5FBC}\x{5FBD}\x{5FC3}\x{5FC5}\x{5FCC}\x{5FCD}\x{5FD6}\x{5FD7}' - . '\x{5FD8}\x{5FD9}\x{5FDC}\x{5FDD}\x{5FE0}\x{5FE4}\x{5FEB}\x{5FF0}\x{5FF1}' - . '\x{5FF5}\x{5FF8}\x{5FFB}\x{5FFD}\x{5FFF}\x{600E}\x{600F}\x{6010}\x{6012}' - . '\x{6015}\x{6016}\x{6019}\x{601B}\x{601C}\x{601D}\x{6020}\x{6021}\x{6025}' - . '\x{6026}\x{6027}\x{6028}\x{6029}\x{602A}\x{602B}\x{602F}\x{6031}\x{603A}' - . '\x{6041}\x{6042}\x{6043}\x{6046}\x{604A}\x{604B}\x{604D}\x{6050}\x{6052}' - . '\x{6055}\x{6059}\x{605A}\x{605F}\x{6060}\x{6062}\x{6063}\x{6064}\x{6065}' - . '\x{6068}\x{6069}\x{606A}\x{606B}\x{606C}\x{606D}\x{606F}\x{6070}\x{6075}' - . '\x{6077}\x{6081}\x{6083}\x{6084}\x{6089}\x{608B}\x{608C}\x{608D}\x{6092}' - . '\x{6094}\x{6096}\x{6097}\x{609A}\x{609B}\x{609F}\x{60A0}\x{60A3}\x{60A6}' - . '\x{60A7}\x{60A9}\x{60AA}\x{60B2}\x{60B3}\x{60B4}\x{60B5}\x{60B6}\x{60B8}' - . '\x{60BC}\x{60BD}\x{60C5}\x{60C6}\x{60C7}\x{60D1}\x{60D3}\x{60D8}\x{60DA}' - . '\x{60DC}\x{60DF}\x{60E0}\x{60E1}\x{60E3}\x{60E7}\x{60E8}\x{60F0}\x{60F1}' - . '\x{60F3}\x{60F4}\x{60F6}\x{60F7}\x{60F9}\x{60FA}\x{60FB}\x{6100}\x{6101}' - . '\x{6103}\x{6106}\x{6108}\x{6109}\x{610D}\x{610E}\x{610F}\x{6115}\x{611A}' - . '\x{611B}\x{611F}\x{6121}\x{6127}\x{6128}\x{612C}\x{6134}\x{613C}\x{613D}' - . '\x{613E}\x{613F}\x{6142}\x{6144}\x{6147}\x{6148}\x{614A}\x{614B}\x{614C}' - . '\x{614D}\x{614E}\x{6153}\x{6155}\x{6158}\x{6159}\x{615A}\x{615D}\x{615F}' - . '\x{6162}\x{6163}\x{6165}\x{6167}\x{6168}\x{616B}\x{616E}\x{616F}\x{6170}' - . '\x{6171}\x{6173}\x{6174}\x{6175}\x{6176}\x{6177}\x{617E}\x{6182}\x{6187}' - . '\x{618A}\x{618E}\x{6190}\x{6191}\x{6194}\x{6196}\x{6199}\x{619A}\x{61A4}' - . '\x{61A7}\x{61A9}\x{61AB}\x{61AC}\x{61AE}\x{61B2}\x{61B6}\x{61BA}\x{61BE}' - . '\x{61C3}\x{61C6}\x{61C7}\x{61C8}\x{61C9}\x{61CA}\x{61CB}\x{61CC}\x{61CD}' - . '\x{61D0}\x{61E3}\x{61E6}\x{61F2}\x{61F4}\x{61F6}\x{61F7}\x{61F8}\x{61FA}' - . '\x{61FC}\x{61FD}\x{61FE}\x{61FF}\x{6200}\x{6208}\x{6209}\x{620A}\x{620C}' - . '\x{620D}\x{620E}\x{6210}\x{6211}\x{6212}\x{6214}\x{6216}\x{621A}\x{621B}' - . '\x{621D}\x{621E}\x{621F}\x{6221}\x{6226}\x{622A}\x{622E}\x{622F}\x{6230}' - . '\x{6232}\x{6233}\x{6234}\x{6238}\x{623B}\x{623F}\x{6240}\x{6241}\x{6247}' - . '\x{6248}\x{6249}\x{624B}\x{624D}\x{624E}\x{6253}\x{6255}\x{6258}\x{625B}' - . '\x{625E}\x{6260}\x{6263}\x{6268}\x{626E}\x{6271}\x{6276}\x{6279}\x{627C}' - . '\x{627E}\x{627F}\x{6280}\x{6282}\x{6283}\x{6284}\x{6289}\x{628A}\x{6291}' - . '\x{6292}\x{6293}\x{6294}\x{6295}\x{6296}\x{6297}\x{6298}\x{629B}\x{629C}' - . '\x{629E}\x{62AB}\x{62AC}\x{62B1}\x{62B5}\x{62B9}\x{62BB}\x{62BC}\x{62BD}' - . '\x{62C2}\x{62C5}\x{62C6}\x{62C7}\x{62C8}\x{62C9}\x{62CA}\x{62CC}\x{62CD}' - . '\x{62CF}\x{62D0}\x{62D1}\x{62D2}\x{62D3}\x{62D4}\x{62D7}\x{62D8}\x{62D9}' - . '\x{62DB}\x{62DC}\x{62DD}\x{62E0}\x{62E1}\x{62EC}\x{62ED}\x{62EE}\x{62EF}' - . '\x{62F1}\x{62F3}\x{62F5}\x{62F6}\x{62F7}\x{62FE}\x{62FF}\x{6301}\x{6302}' - . '\x{6307}\x{6308}\x{6309}\x{630C}\x{6311}\x{6319}\x{631F}\x{6327}\x{6328}' - . '\x{632B}\x{632F}\x{633A}\x{633D}\x{633E}\x{633F}\x{6349}\x{634C}\x{634D}' - . '\x{634F}\x{6350}\x{6355}\x{6357}\x{635C}\x{6367}\x{6368}\x{6369}\x{636B}' - . '\x{636E}\x{6372}\x{6376}\x{6377}\x{637A}\x{637B}\x{6380}\x{6383}\x{6388}' - . '\x{6389}\x{638C}\x{638E}\x{638F}\x{6392}\x{6396}\x{6398}\x{639B}\x{639F}' - . '\x{63A0}\x{63A1}\x{63A2}\x{63A3}\x{63A5}\x{63A7}\x{63A8}\x{63A9}\x{63AA}' - . '\x{63AB}\x{63AC}\x{63B2}\x{63B4}\x{63B5}\x{63BB}\x{63BE}\x{63C0}\x{63C3}' - . '\x{63C4}\x{63C6}\x{63C9}\x{63CF}\x{63D0}\x{63D2}\x{63D6}\x{63DA}\x{63DB}' - . '\x{63E1}\x{63E3}\x{63E9}\x{63EE}\x{63F4}\x{63F6}\x{63FA}\x{6406}\x{640D}' - . '\x{640F}\x{6413}\x{6416}\x{6417}\x{641C}\x{6426}\x{6428}\x{642C}\x{642D}' - . '\x{6434}\x{6436}\x{643A}\x{643E}\x{6442}\x{644E}\x{6458}\x{6467}\x{6469}' - . '\x{646F}\x{6476}\x{6478}\x{647A}\x{6483}\x{6488}\x{6492}\x{6493}\x{6495}' - . '\x{649A}\x{649E}\x{64A4}\x{64A5}\x{64A9}\x{64AB}\x{64AD}\x{64AE}\x{64B0}' - . '\x{64B2}\x{64B9}\x{64BB}\x{64BC}\x{64C1}\x{64C2}\x{64C5}\x{64C7}\x{64CD}' - . '\x{64D2}\x{64D4}\x{64D8}\x{64DA}\x{64E0}\x{64E1}\x{64E2}\x{64E3}\x{64E6}' - . '\x{64E7}\x{64EC}\x{64EF}\x{64F1}\x{64F2}\x{64F4}\x{64F6}\x{64FA}\x{64FD}' - . '\x{64FE}\x{6500}\x{6505}\x{6518}\x{651C}\x{651D}\x{6523}\x{6524}\x{652A}' - . '\x{652B}\x{652C}\x{652F}\x{6534}\x{6535}\x{6536}\x{6537}\x{6538}\x{6539}' - . '\x{653B}\x{653E}\x{653F}\x{6545}\x{6548}\x{654D}\x{654F}\x{6551}\x{6555}' - . '\x{6556}\x{6557}\x{6558}\x{6559}\x{655D}\x{655E}\x{6562}\x{6563}\x{6566}' - . '\x{656C}\x{6570}\x{6572}\x{6574}\x{6575}\x{6577}\x{6578}\x{6582}\x{6583}' - . '\x{6587}\x{6588}\x{6589}\x{658C}\x{658E}\x{6590}\x{6591}\x{6597}\x{6599}' - . '\x{659B}\x{659C}\x{659F}\x{65A1}\x{65A4}\x{65A5}\x{65A7}\x{65AB}\x{65AC}' - . '\x{65AD}\x{65AF}\x{65B0}\x{65B7}\x{65B9}\x{65BC}\x{65BD}\x{65C1}\x{65C3}' - . '\x{65C4}\x{65C5}\x{65C6}\x{65CB}\x{65CC}\x{65CF}\x{65D2}\x{65D7}\x{65D9}' - . '\x{65DB}\x{65E0}\x{65E1}\x{65E2}\x{65E5}\x{65E6}\x{65E7}\x{65E8}\x{65E9}' - . '\x{65EC}\x{65ED}\x{65F1}\x{65FA}\x{65FB}\x{6602}\x{6603}\x{6606}\x{6607}' - . '\x{660A}\x{660C}\x{660E}\x{660F}\x{6613}\x{6614}\x{661C}\x{661F}\x{6620}' - . '\x{6625}\x{6627}\x{6628}\x{662D}\x{662F}\x{6634}\x{6635}\x{6636}\x{663C}' - . '\x{663F}\x{6641}\x{6642}\x{6643}\x{6644}\x{6649}\x{664B}\x{664F}\x{6652}' - . '\x{665D}\x{665E}\x{665F}\x{6662}\x{6664}\x{6666}\x{6667}\x{6668}\x{6669}' - . '\x{666E}\x{666F}\x{6670}\x{6674}\x{6676}\x{667A}\x{6681}\x{6683}\x{6684}' - . '\x{6687}\x{6688}\x{6689}\x{668E}\x{6691}\x{6696}\x{6697}\x{6698}\x{669D}' - . '\x{66A2}\x{66A6}\x{66AB}\x{66AE}\x{66B4}\x{66B8}\x{66B9}\x{66BC}\x{66BE}' - . '\x{66C1}\x{66C4}\x{66C7}\x{66C9}\x{66D6}\x{66D9}\x{66DA}\x{66DC}\x{66DD}' - . '\x{66E0}\x{66E6}\x{66E9}\x{66F0}\x{66F2}\x{66F3}\x{66F4}\x{66F5}\x{66F7}' - . '\x{66F8}\x{66F9}\x{66FC}\x{66FD}\x{66FE}\x{66FF}\x{6700}\x{6703}\x{6708}' - . '\x{6709}\x{670B}\x{670D}\x{670F}\x{6714}\x{6715}\x{6716}\x{6717}\x{671B}' - . '\x{671D}\x{671E}\x{671F}\x{6726}\x{6727}\x{6728}\x{672A}\x{672B}\x{672C}' - . '\x{672D}\x{672E}\x{6731}\x{6734}\x{6736}\x{6737}\x{6738}\x{673A}\x{673D}' - . '\x{673F}\x{6741}\x{6746}\x{6749}\x{674E}\x{674F}\x{6750}\x{6751}\x{6753}' - . '\x{6756}\x{6759}\x{675C}\x{675E}\x{675F}\x{6760}\x{6761}\x{6762}\x{6763}' - . '\x{6764}\x{6765}\x{676A}\x{676D}\x{676F}\x{6770}\x{6771}\x{6772}\x{6773}' - . '\x{6775}\x{6777}\x{677C}\x{677E}\x{677F}\x{6785}\x{6787}\x{6789}\x{678B}' - . '\x{678C}\x{6790}\x{6795}\x{6797}\x{679A}\x{679C}\x{679D}\x{67A0}\x{67A1}' - . '\x{67A2}\x{67A6}\x{67A9}\x{67AF}\x{67B3}\x{67B4}\x{67B6}\x{67B7}\x{67B8}' - . '\x{67B9}\x{67C1}\x{67C4}\x{67C6}\x{67CA}\x{67CE}\x{67CF}\x{67D0}\x{67D1}' - . '\x{67D3}\x{67D4}\x{67D8}\x{67DA}\x{67DD}\x{67DE}\x{67E2}\x{67E4}\x{67E7}' - . '\x{67E9}\x{67EC}\x{67EE}\x{67EF}\x{67F1}\x{67F3}\x{67F4}\x{67F5}\x{67FB}' - . '\x{67FE}\x{67FF}\x{6802}\x{6803}\x{6804}\x{6813}\x{6816}\x{6817}\x{681E}' - . '\x{6821}\x{6822}\x{6829}\x{682A}\x{682B}\x{6832}\x{6834}\x{6838}\x{6839}' - . '\x{683C}\x{683D}\x{6840}\x{6841}\x{6842}\x{6843}\x{6846}\x{6848}\x{684D}' - . '\x{684E}\x{6850}\x{6851}\x{6853}\x{6854}\x{6859}\x{685C}\x{685D}\x{685F}' - . '\x{6863}\x{6867}\x{6874}\x{6876}\x{6877}\x{687E}\x{687F}\x{6881}\x{6883}' - . '\x{6885}\x{688D}\x{688F}\x{6893}\x{6894}\x{6897}\x{689B}\x{689D}\x{689F}' - . '\x{68A0}\x{68A2}\x{68A6}\x{68A7}\x{68A8}\x{68AD}\x{68AF}\x{68B0}\x{68B1}' - . '\x{68B3}\x{68B5}\x{68B6}\x{68B9}\x{68BA}\x{68BC}\x{68C4}\x{68C6}\x{68C9}' - . '\x{68CA}\x{68CB}\x{68CD}\x{68D2}\x{68D4}\x{68D5}\x{68D7}\x{68D8}\x{68DA}' - . '\x{68DF}\x{68E0}\x{68E1}\x{68E3}\x{68E7}\x{68EE}\x{68EF}\x{68F2}\x{68F9}' - . '\x{68FA}\x{6900}\x{6901}\x{6904}\x{6905}\x{6908}\x{690B}\x{690C}\x{690D}' - . '\x{690E}\x{690F}\x{6912}\x{6919}\x{691A}\x{691B}\x{691C}\x{6921}\x{6922}' - . '\x{6923}\x{6925}\x{6926}\x{6928}\x{692A}\x{6930}\x{6934}\x{6936}\x{6939}' - . '\x{693D}\x{693F}\x{694A}\x{6953}\x{6954}\x{6955}\x{6959}\x{695A}\x{695C}' - . '\x{695D}\x{695E}\x{6960}\x{6961}\x{6962}\x{696A}\x{696B}\x{696D}\x{696E}' - . '\x{696F}\x{6973}\x{6974}\x{6975}\x{6977}\x{6978}\x{6979}\x{697C}\x{697D}' - . '\x{697E}\x{6981}\x{6982}\x{698A}\x{698E}\x{6991}\x{6994}\x{6995}\x{699B}' - . '\x{699C}\x{69A0}\x{69A7}\x{69AE}\x{69B1}\x{69B2}\x{69B4}\x{69BB}\x{69BE}' - . '\x{69BF}\x{69C1}\x{69C3}\x{69C7}\x{69CA}\x{69CB}\x{69CC}\x{69CD}\x{69CE}' - . '\x{69D0}\x{69D3}\x{69D8}\x{69D9}\x{69DD}\x{69DE}\x{69E7}\x{69E8}\x{69EB}' - . '\x{69ED}\x{69F2}\x{69F9}\x{69FB}\x{69FD}\x{69FF}\x{6A02}\x{6A05}\x{6A0A}' - . '\x{6A0B}\x{6A0C}\x{6A12}\x{6A13}\x{6A14}\x{6A17}\x{6A19}\x{6A1B}\x{6A1E}' - . '\x{6A1F}\x{6A21}\x{6A22}\x{6A23}\x{6A29}\x{6A2A}\x{6A2B}\x{6A2E}\x{6A35}' - . '\x{6A36}\x{6A38}\x{6A39}\x{6A3A}\x{6A3D}\x{6A44}\x{6A47}\x{6A48}\x{6A4B}' - . '\x{6A58}\x{6A59}\x{6A5F}\x{6A61}\x{6A62}\x{6A66}\x{6A72}\x{6A78}\x{6A7F}' - . '\x{6A80}\x{6A84}\x{6A8D}\x{6A8E}\x{6A90}\x{6A97}\x{6A9C}\x{6AA0}\x{6AA2}' - . '\x{6AA3}\x{6AAA}\x{6AAC}\x{6AAE}\x{6AB3}\x{6AB8}\x{6ABB}\x{6AC1}\x{6AC2}' - . '\x{6AC3}\x{6AD1}\x{6AD3}\x{6ADA}\x{6ADB}\x{6ADE}\x{6ADF}\x{6AE8}\x{6AEA}' - . '\x{6AFA}\x{6AFB}\x{6B04}\x{6B05}\x{6B0A}\x{6B12}\x{6B16}\x{6B1D}\x{6B1F}' - . '\x{6B20}\x{6B21}\x{6B23}\x{6B27}\x{6B32}\x{6B37}\x{6B38}\x{6B39}\x{6B3A}' - . '\x{6B3D}\x{6B3E}\x{6B43}\x{6B47}\x{6B49}\x{6B4C}\x{6B4E}\x{6B50}\x{6B53}' - . '\x{6B54}\x{6B59}\x{6B5B}\x{6B5F}\x{6B61}\x{6B62}\x{6B63}\x{6B64}\x{6B66}' - . '\x{6B69}\x{6B6A}\x{6B6F}\x{6B73}\x{6B74}\x{6B78}\x{6B79}\x{6B7B}\x{6B7F}' - . '\x{6B80}\x{6B83}\x{6B84}\x{6B86}\x{6B89}\x{6B8A}\x{6B8B}\x{6B8D}\x{6B95}' - . '\x{6B96}\x{6B98}\x{6B9E}\x{6BA4}\x{6BAA}\x{6BAB}\x{6BAF}\x{6BB1}\x{6BB2}' - . '\x{6BB3}\x{6BB4}\x{6BB5}\x{6BB7}\x{6BBA}\x{6BBB}\x{6BBC}\x{6BBF}\x{6BC0}' - . '\x{6BC5}\x{6BC6}\x{6BCB}\x{6BCD}\x{6BCE}\x{6BD2}\x{6BD3}\x{6BD4}\x{6BD8}' - . '\x{6BDB}\x{6BDF}\x{6BEB}\x{6BEC}\x{6BEF}\x{6BF3}\x{6C08}\x{6C0F}\x{6C11}' - . '\x{6C13}\x{6C14}\x{6C17}\x{6C1B}\x{6C23}\x{6C24}\x{6C34}\x{6C37}\x{6C38}' - . '\x{6C3E}\x{6C40}\x{6C41}\x{6C42}\x{6C4E}\x{6C50}\x{6C55}\x{6C57}\x{6C5A}' - . '\x{6C5D}\x{6C5E}\x{6C5F}\x{6C60}\x{6C62}\x{6C68}\x{6C6A}\x{6C70}\x{6C72}' - . '\x{6C73}\x{6C7A}\x{6C7D}\x{6C7E}\x{6C81}\x{6C82}\x{6C83}\x{6C88}\x{6C8C}' - . '\x{6C8D}\x{6C90}\x{6C92}\x{6C93}\x{6C96}\x{6C99}\x{6C9A}\x{6C9B}\x{6CA1}' - . '\x{6CA2}\x{6CAB}\x{6CAE}\x{6CB1}\x{6CB3}\x{6CB8}\x{6CB9}\x{6CBA}\x{6CBB}' - . '\x{6CBC}\x{6CBD}\x{6CBE}\x{6CBF}\x{6CC1}\x{6CC4}\x{6CC5}\x{6CC9}\x{6CCA}' - . '\x{6CCC}\x{6CD3}\x{6CD5}\x{6CD7}\x{6CD9}\x{6CDB}\x{6CDD}\x{6CE1}\x{6CE2}' - . '\x{6CE3}\x{6CE5}\x{6CE8}\x{6CEA}\x{6CEF}\x{6CF0}\x{6CF1}\x{6CF3}\x{6D0B}' - . '\x{6D0C}\x{6D12}\x{6D17}\x{6D19}\x{6D1B}\x{6D1E}\x{6D1F}\x{6D25}\x{6D29}' - . '\x{6D2A}\x{6D2B}\x{6D32}\x{6D33}\x{6D35}\x{6D36}\x{6D38}\x{6D3B}\x{6D3D}' - . '\x{6D3E}\x{6D41}\x{6D44}\x{6D45}\x{6D59}\x{6D5A}\x{6D5C}\x{6D63}\x{6D64}' - . '\x{6D66}\x{6D69}\x{6D6A}\x{6D6C}\x{6D6E}\x{6D74}\x{6D77}\x{6D78}\x{6D79}' - . '\x{6D85}\x{6D88}\x{6D8C}\x{6D8E}\x{6D93}\x{6D95}\x{6D99}\x{6D9B}\x{6D9C}' - . '\x{6DAF}\x{6DB2}\x{6DB5}\x{6DB8}\x{6DBC}\x{6DC0}\x{6DC5}\x{6DC6}\x{6DC7}' - . '\x{6DCB}\x{6DCC}\x{6DD1}\x{6DD2}\x{6DD5}\x{6DD8}\x{6DD9}\x{6DDE}\x{6DE1}' - . '\x{6DE4}\x{6DE6}\x{6DE8}\x{6DEA}\x{6DEB}\x{6DEC}\x{6DEE}\x{6DF1}\x{6DF3}' - . '\x{6DF5}\x{6DF7}\x{6DF9}\x{6DFA}\x{6DFB}\x{6E05}\x{6E07}\x{6E08}\x{6E09}' - . '\x{6E0A}\x{6E0B}\x{6E13}\x{6E15}\x{6E19}\x{6E1A}\x{6E1B}\x{6E1D}\x{6E1F}' - . '\x{6E20}\x{6E21}\x{6E23}\x{6E24}\x{6E25}\x{6E26}\x{6E29}\x{6E2B}\x{6E2C}' - . '\x{6E2D}\x{6E2E}\x{6E2F}\x{6E38}\x{6E3A}\x{6E3E}\x{6E43}\x{6E4A}\x{6E4D}' - . '\x{6E4E}\x{6E56}\x{6E58}\x{6E5B}\x{6E5F}\x{6E67}\x{6E6B}\x{6E6E}\x{6E6F}' - . '\x{6E72}\x{6E76}\x{6E7E}\x{6E7F}\x{6E80}\x{6E82}\x{6E8C}\x{6E8F}\x{6E90}' - . '\x{6E96}\x{6E98}\x{6E9C}\x{6E9D}\x{6E9F}\x{6EA2}\x{6EA5}\x{6EAA}\x{6EAF}' - . '\x{6EB2}\x{6EB6}\x{6EB7}\x{6EBA}\x{6EBD}\x{6EC2}\x{6EC4}\x{6EC5}\x{6EC9}' - . '\x{6ECB}\x{6ECC}\x{6ED1}\x{6ED3}\x{6ED4}\x{6ED5}\x{6EDD}\x{6EDE}\x{6EEC}' - . '\x{6EEF}\x{6EF2}\x{6EF4}\x{6EF7}\x{6EF8}\x{6EFE}\x{6EFF}\x{6F01}\x{6F02}' - . '\x{6F06}\x{6F09}\x{6F0F}\x{6F11}\x{6F13}\x{6F14}\x{6F15}\x{6F20}\x{6F22}' - . '\x{6F23}\x{6F2B}\x{6F2C}\x{6F31}\x{6F32}\x{6F38}\x{6F3E}\x{6F3F}\x{6F41}' - . '\x{6F45}\x{6F54}\x{6F58}\x{6F5B}\x{6F5C}\x{6F5F}\x{6F64}\x{6F66}\x{6F6D}' - . '\x{6F6E}\x{6F6F}\x{6F70}\x{6F74}\x{6F78}\x{6F7A}\x{6F7C}\x{6F80}\x{6F81}' - . '\x{6F82}\x{6F84}\x{6F86}\x{6F8E}\x{6F91}\x{6F97}\x{6FA1}\x{6FA3}\x{6FA4}' - . '\x{6FAA}\x{6FB1}\x{6FB3}\x{6FB9}\x{6FC0}\x{6FC1}\x{6FC2}\x{6FC3}\x{6FC6}' - . '\x{6FD4}\x{6FD5}\x{6FD8}\x{6FDB}\x{6FDF}\x{6FE0}\x{6FE1}\x{6FE4}\x{6FEB}' - . '\x{6FEC}\x{6FEE}\x{6FEF}\x{6FF1}\x{6FF3}\x{6FF6}\x{6FFA}\x{6FFE}\x{7001}' - . '\x{7009}\x{700B}\x{700F}\x{7011}\x{7015}\x{7018}\x{701A}\x{701B}\x{701D}' - . '\x{701E}\x{701F}\x{7026}\x{7027}\x{702C}\x{7030}\x{7032}\x{703E}\x{704C}' - . '\x{7051}\x{7058}\x{7063}\x{706B}\x{706F}\x{7070}\x{7078}\x{707C}\x{707D}' - . '\x{7089}\x{708A}\x{708E}\x{7092}\x{7099}\x{70AC}\x{70AD}\x{70AE}\x{70AF}' - . '\x{70B3}\x{70B8}\x{70B9}\x{70BA}\x{70C8}\x{70CB}\x{70CF}\x{70D9}\x{70DD}' - . '\x{70DF}\x{70F1}\x{70F9}\x{70FD}\x{7109}\x{7114}\x{7119}\x{711A}\x{711C}' - . '\x{7121}\x{7126}\x{7136}\x{713C}\x{7149}\x{714C}\x{714E}\x{7155}\x{7156}' - . '\x{7159}\x{7162}\x{7164}\x{7165}\x{7166}\x{7167}\x{7169}\x{716C}\x{716E}' - . '\x{717D}\x{7184}\x{7188}\x{718A}\x{718F}\x{7194}\x{7195}\x{7199}\x{719F}' - . '\x{71A8}\x{71AC}\x{71B1}\x{71B9}\x{71BE}\x{71C3}\x{71C8}\x{71C9}\x{71CE}' - . '\x{71D0}\x{71D2}\x{71D4}\x{71D5}\x{71D7}\x{71DF}\x{71E0}\x{71E5}\x{71E6}' - . '\x{71E7}\x{71EC}\x{71ED}\x{71EE}\x{71F5}\x{71F9}\x{71FB}\x{71FC}\x{71FF}' - . '\x{7206}\x{720D}\x{7210}\x{721B}\x{7228}\x{722A}\x{722C}\x{722D}\x{7230}' - . '\x{7232}\x{7235}\x{7236}\x{723A}\x{723B}\x{723C}\x{723D}\x{723E}\x{723F}' - . '\x{7240}\x{7246}\x{7247}\x{7248}\x{724B}\x{724C}\x{7252}\x{7258}\x{7259}' - . '\x{725B}\x{725D}\x{725F}\x{7261}\x{7262}\x{7267}\x{7269}\x{7272}\x{7274}' - . '\x{7279}\x{727D}\x{727E}\x{7280}\x{7281}\x{7282}\x{7287}\x{7292}\x{7296}' - . '\x{72A0}\x{72A2}\x{72A7}\x{72AC}\x{72AF}\x{72B2}\x{72B6}\x{72B9}\x{72C2}' - . '\x{72C3}\x{72C4}\x{72C6}\x{72CE}\x{72D0}\x{72D2}\x{72D7}\x{72D9}\x{72DB}' - . '\x{72E0}\x{72E1}\x{72E2}\x{72E9}\x{72EC}\x{72ED}\x{72F7}\x{72F8}\x{72F9}' - . '\x{72FC}\x{72FD}\x{730A}\x{7316}\x{7317}\x{731B}\x{731C}\x{731D}\x{731F}' - . '\x{7325}\x{7329}\x{732A}\x{732B}\x{732E}\x{732F}\x{7334}\x{7336}\x{7337}' - . '\x{733E}\x{733F}\x{7344}\x{7345}\x{734E}\x{734F}\x{7357}\x{7363}\x{7368}' - . '\x{736A}\x{7370}\x{7372}\x{7375}\x{7378}\x{737A}\x{737B}\x{7384}\x{7387}' - . '\x{7389}\x{738B}\x{7396}\x{73A9}\x{73B2}\x{73B3}\x{73BB}\x{73C0}\x{73C2}' - . '\x{73C8}\x{73CA}\x{73CD}\x{73CE}\x{73DE}\x{73E0}\x{73E5}\x{73EA}\x{73ED}' - . '\x{73EE}\x{73F1}\x{73F8}\x{73FE}\x{7403}\x{7405}\x{7406}\x{7409}\x{7422}' - . '\x{7425}\x{7432}\x{7433}\x{7434}\x{7435}\x{7436}\x{743A}\x{743F}\x{7441}' - . '\x{7455}\x{7459}\x{745A}\x{745B}\x{745C}\x{745E}\x{745F}\x{7460}\x{7463}' - . '\x{7464}\x{7469}\x{746A}\x{746F}\x{7470}\x{7473}\x{7476}\x{747E}\x{7483}' - . '\x{748B}\x{749E}\x{74A2}\x{74A7}\x{74B0}\x{74BD}\x{74CA}\x{74CF}\x{74D4}' - . '\x{74DC}\x{74E0}\x{74E2}\x{74E3}\x{74E6}\x{74E7}\x{74E9}\x{74EE}\x{74F0}' - . '\x{74F1}\x{74F2}\x{74F6}\x{74F7}\x{74F8}\x{7503}\x{7504}\x{7505}\x{750C}' - . '\x{750D}\x{750E}\x{7511}\x{7513}\x{7515}\x{7518}\x{751A}\x{751C}\x{751E}' - . '\x{751F}\x{7523}\x{7525}\x{7526}\x{7528}\x{752B}\x{752C}\x{7530}\x{7531}' - . '\x{7532}\x{7533}\x{7537}\x{7538}\x{753A}\x{753B}\x{753C}\x{7544}\x{7546}' - . '\x{7549}\x{754A}\x{754B}\x{754C}\x{754D}\x{754F}\x{7551}\x{7554}\x{7559}' - . '\x{755A}\x{755B}\x{755C}\x{755D}\x{7560}\x{7562}\x{7564}\x{7565}\x{7566}' - . '\x{7567}\x{7569}\x{756A}\x{756B}\x{756D}\x{7570}\x{7573}\x{7574}\x{7576}' - . '\x{7577}\x{7578}\x{757F}\x{7582}\x{7586}\x{7587}\x{7589}\x{758A}\x{758B}' - . '\x{758E}\x{758F}\x{7591}\x{7594}\x{759A}\x{759D}\x{75A3}\x{75A5}\x{75AB}' - . '\x{75B1}\x{75B2}\x{75B3}\x{75B5}\x{75B8}\x{75B9}\x{75BC}\x{75BD}\x{75BE}' - . '\x{75C2}\x{75C3}\x{75C5}\x{75C7}\x{75CA}\x{75CD}\x{75D2}\x{75D4}\x{75D5}' - . '\x{75D8}\x{75D9}\x{75DB}\x{75DE}\x{75E2}\x{75E3}\x{75E9}\x{75F0}\x{75F2}' - . '\x{75F3}\x{75F4}\x{75FA}\x{75FC}\x{75FE}\x{75FF}\x{7601}\x{7609}\x{760B}' - . '\x{760D}\x{761F}\x{7620}\x{7621}\x{7622}\x{7624}\x{7627}\x{7630}\x{7634}' - . '\x{763B}\x{7642}\x{7646}\x{7647}\x{7648}\x{764C}\x{7652}\x{7656}\x{7658}' - . '\x{765C}\x{7661}\x{7662}\x{7667}\x{7668}\x{7669}\x{766A}\x{766C}\x{7670}' - . '\x{7672}\x{7676}\x{7678}\x{767A}\x{767B}\x{767C}\x{767D}\x{767E}\x{7680}' - . '\x{7683}\x{7684}\x{7686}\x{7687}\x{7688}\x{768B}\x{768E}\x{7690}\x{7693}' - . '\x{7696}\x{7699}\x{769A}\x{76AE}\x{76B0}\x{76B4}\x{76B7}\x{76B8}\x{76B9}' - . '\x{76BA}\x{76BF}\x{76C2}\x{76C3}\x{76C6}\x{76C8}\x{76CA}\x{76CD}\x{76D2}' - . '\x{76D6}\x{76D7}\x{76DB}\x{76DC}\x{76DE}\x{76DF}\x{76E1}\x{76E3}\x{76E4}' - . '\x{76E5}\x{76E7}\x{76EA}\x{76EE}\x{76F2}\x{76F4}\x{76F8}\x{76FB}\x{76FE}' - . '\x{7701}\x{7704}\x{7707}\x{7708}\x{7709}\x{770B}\x{770C}\x{771B}\x{771E}' - . '\x{771F}\x{7720}\x{7724}\x{7725}\x{7726}\x{7729}\x{7737}\x{7738}\x{773A}' - . '\x{773C}\x{7740}\x{7747}\x{775A}\x{775B}\x{7761}\x{7763}\x{7765}\x{7766}' - . '\x{7768}\x{776B}\x{7779}\x{777E}\x{777F}\x{778B}\x{778E}\x{7791}\x{779E}' - . '\x{77A0}\x{77A5}\x{77AC}\x{77AD}\x{77B0}\x{77B3}\x{77B6}\x{77B9}\x{77BB}' - . '\x{77BC}\x{77BD}\x{77BF}\x{77C7}\x{77CD}\x{77D7}\x{77DA}\x{77DB}\x{77DC}' - . '\x{77E2}\x{77E3}\x{77E5}\x{77E7}\x{77E9}\x{77ED}\x{77EE}\x{77EF}\x{77F3}' - . '\x{77FC}\x{7802}\x{780C}\x{7812}\x{7814}\x{7815}\x{7820}\x{7825}\x{7826}' - . '\x{7827}\x{7832}\x{7834}\x{783A}\x{783F}\x{7845}\x{785D}\x{786B}\x{786C}' - . '\x{786F}\x{7872}\x{7874}\x{787C}\x{7881}\x{7886}\x{7887}\x{788C}\x{788D}' - . '\x{788E}\x{7891}\x{7893}\x{7895}\x{7897}\x{789A}\x{78A3}\x{78A7}\x{78A9}' - . '\x{78AA}\x{78AF}\x{78B5}\x{78BA}\x{78BC}\x{78BE}\x{78C1}\x{78C5}\x{78C6}' - . '\x{78CA}\x{78CB}\x{78D0}\x{78D1}\x{78D4}\x{78DA}\x{78E7}\x{78E8}\x{78EC}' - . '\x{78EF}\x{78F4}\x{78FD}\x{7901}\x{7907}\x{790E}\x{7911}\x{7912}\x{7919}' - . '\x{7926}\x{792A}\x{792B}\x{792C}\x{793A}\x{793C}\x{793E}\x{7940}\x{7941}' - . '\x{7947}\x{7948}\x{7949}\x{7950}\x{7953}\x{7955}\x{7956}\x{7957}\x{795A}' - . '\x{795D}\x{795E}\x{795F}\x{7960}\x{7962}\x{7965}\x{7968}\x{796D}\x{7977}' - . '\x{797A}\x{797F}\x{7980}\x{7981}\x{7984}\x{7985}\x{798A}\x{798D}\x{798E}' - . '\x{798F}\x{799D}\x{79A6}\x{79A7}\x{79AA}\x{79AE}\x{79B0}\x{79B3}\x{79B9}' - . '\x{79BA}\x{79BD}\x{79BE}\x{79BF}\x{79C0}\x{79C1}\x{79C9}\x{79CB}\x{79D1}' - . '\x{79D2}\x{79D5}\x{79D8}\x{79DF}\x{79E1}\x{79E3}\x{79E4}\x{79E6}\x{79E7}' - . '\x{79E9}\x{79EC}\x{79F0}\x{79FB}\x{7A00}\x{7A08}\x{7A0B}\x{7A0D}\x{7A0E}' - . '\x{7A14}\x{7A17}\x{7A18}\x{7A19}\x{7A1A}\x{7A1C}\x{7A1F}\x{7A20}\x{7A2E}' - . '\x{7A31}\x{7A32}\x{7A37}\x{7A3B}\x{7A3C}\x{7A3D}\x{7A3E}\x{7A3F}\x{7A40}' - . '\x{7A42}\x{7A43}\x{7A46}\x{7A49}\x{7A4D}\x{7A4E}\x{7A4F}\x{7A50}\x{7A57}' - . '\x{7A61}\x{7A62}\x{7A63}\x{7A69}\x{7A6B}\x{7A70}\x{7A74}\x{7A76}\x{7A79}' - . '\x{7A7A}\x{7A7D}\x{7A7F}\x{7A81}\x{7A83}\x{7A84}\x{7A88}\x{7A92}\x{7A93}' - . '\x{7A95}\x{7A96}\x{7A97}\x{7A98}\x{7A9F}\x{7AA9}\x{7AAA}\x{7AAE}\x{7AAF}' - . '\x{7AB0}\x{7AB6}\x{7ABA}\x{7ABF}\x{7AC3}\x{7AC4}\x{7AC5}\x{7AC7}\x{7AC8}' - . '\x{7ACA}\x{7ACB}\x{7ACD}\x{7ACF}\x{7AD2}\x{7AD3}\x{7AD5}\x{7AD9}\x{7ADA}' - . '\x{7ADC}\x{7ADD}\x{7ADF}\x{7AE0}\x{7AE1}\x{7AE2}\x{7AE3}\x{7AE5}\x{7AE6}' - . '\x{7AEA}\x{7AED}\x{7AEF}\x{7AF0}\x{7AF6}\x{7AF8}\x{7AF9}\x{7AFA}\x{7AFF}' - . '\x{7B02}\x{7B04}\x{7B06}\x{7B08}\x{7B0A}\x{7B0B}\x{7B0F}\x{7B11}\x{7B18}' - . '\x{7B19}\x{7B1B}\x{7B1E}\x{7B20}\x{7B25}\x{7B26}\x{7B28}\x{7B2C}\x{7B33}' - . '\x{7B35}\x{7B36}\x{7B39}\x{7B45}\x{7B46}\x{7B48}\x{7B49}\x{7B4B}\x{7B4C}' - . '\x{7B4D}\x{7B4F}\x{7B50}\x{7B51}\x{7B52}\x{7B54}\x{7B56}\x{7B5D}\x{7B65}' - . '\x{7B67}\x{7B6C}\x{7B6E}\x{7B70}\x{7B71}\x{7B74}\x{7B75}\x{7B7A}\x{7B86}' - . '\x{7B87}\x{7B8B}\x{7B8D}\x{7B8F}\x{7B92}\x{7B94}\x{7B95}\x{7B97}\x{7B98}' - . '\x{7B99}\x{7B9A}\x{7B9C}\x{7B9D}\x{7B9F}\x{7BA1}\x{7BAA}\x{7BAD}\x{7BB1}' - . '\x{7BB4}\x{7BB8}\x{7BC0}\x{7BC1}\x{7BC4}\x{7BC6}\x{7BC7}\x{7BC9}\x{7BCB}' - . '\x{7BCC}\x{7BCF}\x{7BDD}\x{7BE0}\x{7BE4}\x{7BE5}\x{7BE6}\x{7BE9}\x{7BED}' - . '\x{7BF3}\x{7BF6}\x{7BF7}\x{7C00}\x{7C07}\x{7C0D}\x{7C11}\x{7C12}\x{7C13}' - . '\x{7C14}\x{7C17}\x{7C1F}\x{7C21}\x{7C23}\x{7C27}\x{7C2A}\x{7C2B}\x{7C37}' - . '\x{7C38}\x{7C3D}\x{7C3E}\x{7C3F}\x{7C40}\x{7C43}\x{7C4C}\x{7C4D}\x{7C4F}' - . '\x{7C50}\x{7C54}\x{7C56}\x{7C58}\x{7C5F}\x{7C60}\x{7C64}\x{7C65}\x{7C6C}' - . '\x{7C73}\x{7C75}\x{7C7E}\x{7C81}\x{7C82}\x{7C83}\x{7C89}\x{7C8B}\x{7C8D}' - . '\x{7C90}\x{7C92}\x{7C95}\x{7C97}\x{7C98}\x{7C9B}\x{7C9F}\x{7CA1}\x{7CA2}' - . '\x{7CA4}\x{7CA5}\x{7CA7}\x{7CA8}\x{7CAB}\x{7CAD}\x{7CAE}\x{7CB1}\x{7CB2}' - . '\x{7CB3}\x{7CB9}\x{7CBD}\x{7CBE}\x{7CC0}\x{7CC2}\x{7CC5}\x{7CCA}\x{7CCE}' - . '\x{7CD2}\x{7CD6}\x{7CD8}\x{7CDC}\x{7CDE}\x{7CDF}\x{7CE0}\x{7CE2}\x{7CE7}' - . '\x{7CEF}\x{7CF2}\x{7CF4}\x{7CF6}\x{7CF8}\x{7CFA}\x{7CFB}\x{7CFE}\x{7D00}' - . '\x{7D02}\x{7D04}\x{7D05}\x{7D06}\x{7D0A}\x{7D0B}\x{7D0D}\x{7D10}\x{7D14}' - . '\x{7D15}\x{7D17}\x{7D18}\x{7D19}\x{7D1A}\x{7D1B}\x{7D1C}\x{7D20}\x{7D21}' - . '\x{7D22}\x{7D2B}\x{7D2C}\x{7D2E}\x{7D2F}\x{7D30}\x{7D32}\x{7D33}\x{7D35}' - . '\x{7D39}\x{7D3A}\x{7D3F}\x{7D42}\x{7D43}\x{7D44}\x{7D45}\x{7D46}\x{7D4B}' - . '\x{7D4C}\x{7D4E}\x{7D4F}\x{7D50}\x{7D56}\x{7D5B}\x{7D5E}\x{7D61}\x{7D62}' - . '\x{7D63}\x{7D66}\x{7D68}\x{7D6E}\x{7D71}\x{7D72}\x{7D73}\x{7D75}\x{7D76}' - . '\x{7D79}\x{7D7D}\x{7D89}\x{7D8F}\x{7D93}\x{7D99}\x{7D9A}\x{7D9B}\x{7D9C}' - . '\x{7D9F}\x{7DA2}\x{7DA3}\x{7DAB}\x{7DAC}\x{7DAD}\x{7DAE}\x{7DAF}\x{7DB0}' - . '\x{7DB1}\x{7DB2}\x{7DB4}\x{7DB5}\x{7DB8}\x{7DBA}\x{7DBB}\x{7DBD}\x{7DBE}' - . '\x{7DBF}\x{7DC7}\x{7DCA}\x{7DCB}\x{7DCF}\x{7DD1}\x{7DD2}\x{7DD5}\x{7DD8}' - . '\x{7DDA}\x{7DDC}\x{7DDD}\x{7DDE}\x{7DE0}\x{7DE1}\x{7DE4}\x{7DE8}\x{7DE9}' - . '\x{7DEC}\x{7DEF}\x{7DF2}\x{7DF4}\x{7DFB}\x{7E01}\x{7E04}\x{7E05}\x{7E09}' - . '\x{7E0A}\x{7E0B}\x{7E12}\x{7E1B}\x{7E1E}\x{7E1F}\x{7E21}\x{7E22}\x{7E23}' - . '\x{7E26}\x{7E2B}\x{7E2E}\x{7E31}\x{7E32}\x{7E35}\x{7E37}\x{7E39}\x{7E3A}' - . '\x{7E3B}\x{7E3D}\x{7E3E}\x{7E41}\x{7E43}\x{7E46}\x{7E4A}\x{7E4B}\x{7E4D}' - . '\x{7E54}\x{7E55}\x{7E56}\x{7E59}\x{7E5A}\x{7E5D}\x{7E5E}\x{7E66}\x{7E67}' - . '\x{7E69}\x{7E6A}\x{7E6D}\x{7E70}\x{7E79}\x{7E7B}\x{7E7C}\x{7E7D}\x{7E7F}' - . '\x{7E82}\x{7E83}\x{7E88}\x{7E89}\x{7E8C}\x{7E8E}\x{7E8F}\x{7E90}\x{7E92}' - . '\x{7E93}\x{7E94}\x{7E96}\x{7E9B}\x{7E9C}\x{7F36}\x{7F38}\x{7F3A}\x{7F45}' - . '\x{7F4C}\x{7F4D}\x{7F4E}\x{7F50}\x{7F51}\x{7F54}\x{7F55}\x{7F58}\x{7F5F}' - . '\x{7F60}\x{7F67}\x{7F68}\x{7F69}\x{7F6A}\x{7F6B}\x{7F6E}\x{7F70}\x{7F72}' - . '\x{7F75}\x{7F77}\x{7F78}\x{7F79}\x{7F82}\x{7F83}\x{7F85}\x{7F86}\x{7F87}' - . '\x{7F88}\x{7F8A}\x{7F8C}\x{7F8E}\x{7F94}\x{7F9A}\x{7F9D}\x{7F9E}\x{7FA3}' - . '\x{7FA4}\x{7FA8}\x{7FA9}\x{7FAE}\x{7FAF}\x{7FB2}\x{7FB6}\x{7FB8}\x{7FB9}' - . '\x{7FBD}\x{7FC1}\x{7FC5}\x{7FC6}\x{7FCA}\x{7FCC}\x{7FD2}\x{7FD4}\x{7FD5}' - . '\x{7FE0}\x{7FE1}\x{7FE6}\x{7FE9}\x{7FEB}\x{7FF0}\x{7FF3}\x{7FF9}\x{7FFB}' - . '\x{7FFC}\x{8000}\x{8001}\x{8003}\x{8004}\x{8005}\x{8006}\x{800B}\x{800C}' - . '\x{8010}\x{8012}\x{8015}\x{8017}\x{8018}\x{8019}\x{801C}\x{8021}\x{8028}' - . '\x{8033}\x{8036}\x{803B}\x{803D}\x{803F}\x{8046}\x{804A}\x{8052}\x{8056}' - . '\x{8058}\x{805A}\x{805E}\x{805F}\x{8061}\x{8062}\x{8068}\x{806F}\x{8070}' - . '\x{8072}\x{8073}\x{8074}\x{8076}\x{8077}\x{8079}\x{807D}\x{807E}\x{807F}' - . '\x{8084}\x{8085}\x{8086}\x{8087}\x{8089}\x{808B}\x{808C}\x{8093}\x{8096}' - . '\x{8098}\x{809A}\x{809B}\x{809D}\x{80A1}\x{80A2}\x{80A5}\x{80A9}\x{80AA}' - . '\x{80AC}\x{80AD}\x{80AF}\x{80B1}\x{80B2}\x{80B4}\x{80BA}\x{80C3}\x{80C4}' - . '\x{80C6}\x{80CC}\x{80CE}\x{80D6}\x{80D9}\x{80DA}\x{80DB}\x{80DD}\x{80DE}' - . '\x{80E1}\x{80E4}\x{80E5}\x{80EF}\x{80F1}\x{80F4}\x{80F8}\x{80FC}\x{80FD}' - . '\x{8102}\x{8105}\x{8106}\x{8107}\x{8108}\x{8109}\x{810A}\x{811A}\x{811B}' - . '\x{8123}\x{8129}\x{812F}\x{8131}\x{8133}\x{8139}\x{813E}\x{8146}\x{814B}' - . '\x{814E}\x{8150}\x{8151}\x{8153}\x{8154}\x{8155}\x{815F}\x{8165}\x{8166}' - . '\x{816B}\x{816E}\x{8170}\x{8171}\x{8174}\x{8178}\x{8179}\x{817A}\x{817F}' - . '\x{8180}\x{8182}\x{8183}\x{8188}\x{818A}\x{818F}\x{8193}\x{8195}\x{819A}' - . '\x{819C}\x{819D}\x{81A0}\x{81A3}\x{81A4}\x{81A8}\x{81A9}\x{81B0}\x{81B3}' - . '\x{81B5}\x{81B8}\x{81BA}\x{81BD}\x{81BE}\x{81BF}\x{81C0}\x{81C2}\x{81C6}' - . '\x{81C8}\x{81C9}\x{81CD}\x{81D1}\x{81D3}\x{81D8}\x{81D9}\x{81DA}\x{81DF}' - . '\x{81E0}\x{81E3}\x{81E5}\x{81E7}\x{81E8}\x{81EA}\x{81ED}\x{81F3}\x{81F4}' - . '\x{81FA}\x{81FB}\x{81FC}\x{81FE}\x{8201}\x{8202}\x{8205}\x{8207}\x{8208}' - . '\x{8209}\x{820A}\x{820C}\x{820D}\x{820E}\x{8210}\x{8212}\x{8216}\x{8217}' - . '\x{8218}\x{821B}\x{821C}\x{821E}\x{821F}\x{8229}\x{822A}\x{822B}\x{822C}' - . '\x{822E}\x{8233}\x{8235}\x{8236}\x{8237}\x{8238}\x{8239}\x{8240}\x{8247}' - . '\x{8258}\x{8259}\x{825A}\x{825D}\x{825F}\x{8262}\x{8264}\x{8266}\x{8268}' - . '\x{826A}\x{826B}\x{826E}\x{826F}\x{8271}\x{8272}\x{8276}\x{8277}\x{8278}' - . '\x{827E}\x{828B}\x{828D}\x{8292}\x{8299}\x{829D}\x{829F}\x{82A5}\x{82A6}' - . '\x{82AB}\x{82AC}\x{82AD}\x{82AF}\x{82B1}\x{82B3}\x{82B8}\x{82B9}\x{82BB}' - . '\x{82BD}\x{82C5}\x{82D1}\x{82D2}\x{82D3}\x{82D4}\x{82D7}\x{82D9}\x{82DB}' - . '\x{82DC}\x{82DE}\x{82DF}\x{82E1}\x{82E3}\x{82E5}\x{82E6}\x{82E7}\x{82EB}' - . '\x{82F1}\x{82F3}\x{82F4}\x{82F9}\x{82FA}\x{82FB}\x{8302}\x{8303}\x{8304}' - . '\x{8305}\x{8306}\x{8309}\x{830E}\x{8316}\x{8317}\x{8318}\x{831C}\x{8323}' - . '\x{8328}\x{832B}\x{832F}\x{8331}\x{8332}\x{8334}\x{8335}\x{8336}\x{8338}' - . '\x{8339}\x{8340}\x{8345}\x{8349}\x{834A}\x{834F}\x{8350}\x{8352}\x{8358}' - . '\x{8373}\x{8375}\x{8377}\x{837B}\x{837C}\x{8385}\x{8387}\x{8389}\x{838A}' - . '\x{838E}\x{8393}\x{8396}\x{839A}\x{839E}\x{839F}\x{83A0}\x{83A2}\x{83A8}' - . '\x{83AA}\x{83AB}\x{83B1}\x{83B5}\x{83BD}\x{83C1}\x{83C5}\x{83CA}\x{83CC}' - . '\x{83CE}\x{83D3}\x{83D6}\x{83D8}\x{83DC}\x{83DF}\x{83E0}\x{83E9}\x{83EB}' - . '\x{83EF}\x{83F0}\x{83F1}\x{83F2}\x{83F4}\x{83F7}\x{83FB}\x{83FD}\x{8403}' - . '\x{8404}\x{8407}\x{840B}\x{840C}\x{840D}\x{840E}\x{8413}\x{8420}\x{8422}' - . '\x{8429}\x{842A}\x{842C}\x{8431}\x{8435}\x{8438}\x{843C}\x{843D}\x{8446}' - . '\x{8449}\x{844E}\x{8457}\x{845B}\x{8461}\x{8462}\x{8463}\x{8466}\x{8469}' - . '\x{846B}\x{846C}\x{846D}\x{846E}\x{846F}\x{8471}\x{8475}\x{8477}\x{8479}' - . '\x{847A}\x{8482}\x{8484}\x{848B}\x{8490}\x{8494}\x{8499}\x{849C}\x{849F}' - . '\x{84A1}\x{84AD}\x{84B2}\x{84B8}\x{84B9}\x{84BB}\x{84BC}\x{84BF}\x{84C1}' - . '\x{84C4}\x{84C6}\x{84C9}\x{84CA}\x{84CB}\x{84CD}\x{84D0}\x{84D1}\x{84D6}' - . '\x{84D9}\x{84DA}\x{84EC}\x{84EE}\x{84F4}\x{84FC}\x{84FF}\x{8500}\x{8506}' - . '\x{8511}\x{8513}\x{8514}\x{8515}\x{8517}\x{8518}\x{851A}\x{851F}\x{8521}' - . '\x{8526}\x{852C}\x{852D}\x{8535}\x{853D}\x{8540}\x{8541}\x{8543}\x{8548}' - . '\x{8549}\x{854A}\x{854B}\x{854E}\x{8555}\x{8557}\x{8558}\x{855A}\x{8563}' - . '\x{8568}\x{8569}\x{856A}\x{856D}\x{8577}\x{857E}\x{8580}\x{8584}\x{8587}' - . '\x{8588}\x{858A}\x{8590}\x{8591}\x{8594}\x{8597}\x{8599}\x{859B}\x{859C}' - . '\x{85A4}\x{85A6}\x{85A8}\x{85A9}\x{85AA}\x{85AB}\x{85AC}\x{85AE}\x{85AF}' - . '\x{85B9}\x{85BA}\x{85C1}\x{85C9}\x{85CD}\x{85CF}\x{85D0}\x{85D5}\x{85DC}' - . '\x{85DD}\x{85E4}\x{85E5}\x{85E9}\x{85EA}\x{85F7}\x{85F9}\x{85FA}\x{85FB}' - . '\x{85FE}\x{8602}\x{8606}\x{8607}\x{860A}\x{860B}\x{8613}\x{8616}\x{8617}' - . '\x{861A}\x{8622}\x{862D}\x{862F}\x{8630}\x{863F}\x{864D}\x{864E}\x{8650}' - . '\x{8654}\x{8655}\x{865A}\x{865C}\x{865E}\x{865F}\x{8667}\x{866B}\x{8671}' - . '\x{8679}\x{867B}\x{868A}\x{868B}\x{868C}\x{8693}\x{8695}\x{86A3}\x{86A4}' - . '\x{86A9}\x{86AA}\x{86AB}\x{86AF}\x{86B0}\x{86B6}\x{86C4}\x{86C6}\x{86C7}' - . '\x{86C9}\x{86CB}\x{86CD}\x{86CE}\x{86D4}\x{86D9}\x{86DB}\x{86DE}\x{86DF}' - . '\x{86E4}\x{86E9}\x{86EC}\x{86ED}\x{86EE}\x{86EF}\x{86F8}\x{86F9}\x{86FB}' - . '\x{86FE}\x{8700}\x{8702}\x{8703}\x{8706}\x{8708}\x{8709}\x{870A}\x{870D}' - . '\x{8711}\x{8712}\x{8718}\x{871A}\x{871C}\x{8725}\x{8729}\x{8734}\x{8737}' - . '\x{873B}\x{873F}\x{8749}\x{874B}\x{874C}\x{874E}\x{8753}\x{8755}\x{8757}' - . '\x{8759}\x{875F}\x{8760}\x{8763}\x{8766}\x{8768}\x{876A}\x{876E}\x{8774}' - . '\x{8776}\x{8778}\x{877F}\x{8782}\x{878D}\x{879F}\x{87A2}\x{87AB}\x{87AF}' - . '\x{87B3}\x{87BA}\x{87BB}\x{87BD}\x{87C0}\x{87C4}\x{87C6}\x{87C7}\x{87CB}' - . '\x{87D0}\x{87D2}\x{87E0}\x{87EF}\x{87F2}\x{87F6}\x{87F7}\x{87F9}\x{87FB}' - . '\x{87FE}\x{8805}\x{880D}\x{880E}\x{880F}\x{8811}\x{8815}\x{8816}\x{8821}' - . '\x{8822}\x{8823}\x{8827}\x{8831}\x{8836}\x{8839}\x{883B}\x{8840}\x{8842}' - . '\x{8844}\x{8846}\x{884C}\x{884D}\x{8852}\x{8853}\x{8857}\x{8859}\x{885B}' - . '\x{885D}\x{885E}\x{8861}\x{8862}\x{8863}\x{8868}\x{886B}\x{8870}\x{8872}' - . '\x{8875}\x{8877}\x{887D}\x{887E}\x{887F}\x{8881}\x{8882}\x{8888}\x{888B}' - . '\x{888D}\x{8892}\x{8896}\x{8897}\x{8899}\x{889E}\x{88A2}\x{88A4}\x{88AB}' - . '\x{88AE}\x{88B0}\x{88B1}\x{88B4}\x{88B5}\x{88B7}\x{88BF}\x{88C1}\x{88C2}' - . '\x{88C3}\x{88C4}\x{88C5}\x{88CF}\x{88D4}\x{88D5}\x{88D8}\x{88D9}\x{88DC}' - . '\x{88DD}\x{88DF}\x{88E1}\x{88E8}\x{88F2}\x{88F3}\x{88F4}\x{88F8}\x{88F9}' - . '\x{88FC}\x{88FD}\x{88FE}\x{8902}\x{8904}\x{8907}\x{890A}\x{890C}\x{8910}' - . '\x{8912}\x{8913}\x{891D}\x{891E}\x{8925}\x{892A}\x{892B}\x{8936}\x{8938}' - . '\x{893B}\x{8941}\x{8943}\x{8944}\x{894C}\x{894D}\x{8956}\x{895E}\x{895F}' - . '\x{8960}\x{8964}\x{8966}\x{896A}\x{896D}\x{896F}\x{8972}\x{8974}\x{8977}' - . '\x{897E}\x{897F}\x{8981}\x{8983}\x{8986}\x{8987}\x{8988}\x{898A}\x{898B}' - . '\x{898F}\x{8993}\x{8996}\x{8997}\x{8998}\x{899A}\x{89A1}\x{89A6}\x{89A7}' - . '\x{89A9}\x{89AA}\x{89AC}\x{89AF}\x{89B2}\x{89B3}\x{89BA}\x{89BD}\x{89BF}' - . '\x{89C0}\x{89D2}\x{89DA}\x{89DC}\x{89DD}\x{89E3}\x{89E6}\x{89E7}\x{89F4}' - . '\x{89F8}\x{8A00}\x{8A02}\x{8A03}\x{8A08}\x{8A0A}\x{8A0C}\x{8A0E}\x{8A10}' - . '\x{8A13}\x{8A16}\x{8A17}\x{8A18}\x{8A1B}\x{8A1D}\x{8A1F}\x{8A23}\x{8A25}' - . '\x{8A2A}\x{8A2D}\x{8A31}\x{8A33}\x{8A34}\x{8A36}\x{8A3A}\x{8A3B}\x{8A3C}' - . '\x{8A41}\x{8A46}\x{8A48}\x{8A50}\x{8A51}\x{8A52}\x{8A54}\x{8A55}\x{8A5B}' - . '\x{8A5E}\x{8A60}\x{8A62}\x{8A63}\x{8A66}\x{8A69}\x{8A6B}\x{8A6C}\x{8A6D}' - . '\x{8A6E}\x{8A70}\x{8A71}\x{8A72}\x{8A73}\x{8A7C}\x{8A82}\x{8A84}\x{8A85}' - . '\x{8A87}\x{8A89}\x{8A8C}\x{8A8D}\x{8A91}\x{8A93}\x{8A95}\x{8A98}\x{8A9A}' - . '\x{8A9E}\x{8AA0}\x{8AA1}\x{8AA3}\x{8AA4}\x{8AA5}\x{8AA6}\x{8AA8}\x{8AAC}' - . '\x{8AAD}\x{8AB0}\x{8AB2}\x{8AB9}\x{8ABC}\x{8ABF}\x{8AC2}\x{8AC4}\x{8AC7}' - . '\x{8ACB}\x{8ACC}\x{8ACD}\x{8ACF}\x{8AD2}\x{8AD6}\x{8ADA}\x{8ADB}\x{8ADC}' - . '\x{8ADE}\x{8AE0}\x{8AE1}\x{8AE2}\x{8AE4}\x{8AE6}\x{8AE7}\x{8AEB}\x{8AED}' - . '\x{8AEE}\x{8AF1}\x{8AF3}\x{8AF7}\x{8AF8}\x{8AFA}\x{8AFE}\x{8B00}\x{8B01}' - . '\x{8B02}\x{8B04}\x{8B07}\x{8B0C}\x{8B0E}\x{8B10}\x{8B14}\x{8B16}\x{8B17}' - . '\x{8B19}\x{8B1A}\x{8B1B}\x{8B1D}\x{8B20}\x{8B21}\x{8B26}\x{8B28}\x{8B2B}' - . '\x{8B2C}\x{8B33}\x{8B39}\x{8B3E}\x{8B41}\x{8B49}\x{8B4C}\x{8B4E}\x{8B4F}' - . '\x{8B56}\x{8B58}\x{8B5A}\x{8B5B}\x{8B5C}\x{8B5F}\x{8B66}\x{8B6B}\x{8B6C}' - . '\x{8B6F}\x{8B70}\x{8B71}\x{8B72}\x{8B74}\x{8B77}\x{8B7D}\x{8B80}\x{8B83}' - . '\x{8B8A}\x{8B8C}\x{8B8E}\x{8B90}\x{8B92}\x{8B93}\x{8B96}\x{8B99}\x{8B9A}' - . '\x{8C37}\x{8C3A}\x{8C3F}\x{8C41}\x{8C46}\x{8C48}\x{8C4A}\x{8C4C}\x{8C4E}' - . '\x{8C50}\x{8C55}\x{8C5A}\x{8C61}\x{8C62}\x{8C6A}\x{8C6B}\x{8C6C}\x{8C78}' - . '\x{8C79}\x{8C7A}\x{8C7C}\x{8C82}\x{8C85}\x{8C89}\x{8C8A}\x{8C8C}\x{8C8D}' - . '\x{8C8E}\x{8C94}\x{8C98}\x{8C9D}\x{8C9E}\x{8CA0}\x{8CA1}\x{8CA2}\x{8CA7}' - . '\x{8CA8}\x{8CA9}\x{8CAA}\x{8CAB}\x{8CAC}\x{8CAD}\x{8CAE}\x{8CAF}\x{8CB0}' - . '\x{8CB2}\x{8CB3}\x{8CB4}\x{8CB6}\x{8CB7}\x{8CB8}\x{8CBB}\x{8CBC}\x{8CBD}' - . '\x{8CBF}\x{8CC0}\x{8CC1}\x{8CC2}\x{8CC3}\x{8CC4}\x{8CC7}\x{8CC8}\x{8CCA}' - . '\x{8CCD}\x{8CCE}\x{8CD1}\x{8CD3}\x{8CDA}\x{8CDB}\x{8CDC}\x{8CDE}\x{8CE0}' - . '\x{8CE2}\x{8CE3}\x{8CE4}\x{8CE6}\x{8CEA}\x{8CED}\x{8CFA}\x{8CFB}\x{8CFC}' - . '\x{8CFD}\x{8D04}\x{8D05}\x{8D07}\x{8D08}\x{8D0A}\x{8D0B}\x{8D0D}\x{8D0F}' - . '\x{8D10}\x{8D13}\x{8D14}\x{8D16}\x{8D64}\x{8D66}\x{8D67}\x{8D6B}\x{8D6D}' - . '\x{8D70}\x{8D71}\x{8D73}\x{8D74}\x{8D77}\x{8D81}\x{8D85}\x{8D8A}\x{8D99}' - . '\x{8DA3}\x{8DA8}\x{8DB3}\x{8DBA}\x{8DBE}\x{8DC2}\x{8DCB}\x{8DCC}\x{8DCF}' - . '\x{8DD6}\x{8DDA}\x{8DDB}\x{8DDD}\x{8DDF}\x{8DE1}\x{8DE3}\x{8DE8}\x{8DEA}' - . '\x{8DEB}\x{8DEF}\x{8DF3}\x{8DF5}\x{8DFC}\x{8DFF}\x{8E08}\x{8E09}\x{8E0A}' - . '\x{8E0F}\x{8E10}\x{8E1D}\x{8E1E}\x{8E1F}\x{8E2A}\x{8E30}\x{8E34}\x{8E35}' - . '\x{8E42}\x{8E44}\x{8E47}\x{8E48}\x{8E49}\x{8E4A}\x{8E4C}\x{8E50}\x{8E55}' - . '\x{8E59}\x{8E5F}\x{8E60}\x{8E63}\x{8E64}\x{8E72}\x{8E74}\x{8E76}\x{8E7C}' - . '\x{8E81}\x{8E84}\x{8E85}\x{8E87}\x{8E8A}\x{8E8B}\x{8E8D}\x{8E91}\x{8E93}' - . '\x{8E94}\x{8E99}\x{8EA1}\x{8EAA}\x{8EAB}\x{8EAC}\x{8EAF}\x{8EB0}\x{8EB1}' - . '\x{8EBE}\x{8EC5}\x{8EC6}\x{8EC8}\x{8ECA}\x{8ECB}\x{8ECC}\x{8ECD}\x{8ED2}' - . '\x{8EDB}\x{8EDF}\x{8EE2}\x{8EE3}\x{8EEB}\x{8EF8}\x{8EFB}\x{8EFC}\x{8EFD}' - . '\x{8EFE}\x{8F03}\x{8F05}\x{8F09}\x{8F0A}\x{8F0C}\x{8F12}\x{8F13}\x{8F14}' - . '\x{8F15}\x{8F19}\x{8F1B}\x{8F1C}\x{8F1D}\x{8F1F}\x{8F26}\x{8F29}\x{8F2A}' - . '\x{8F2F}\x{8F33}\x{8F38}\x{8F39}\x{8F3B}\x{8F3E}\x{8F3F}\x{8F42}\x{8F44}' - . '\x{8F45}\x{8F46}\x{8F49}\x{8F4C}\x{8F4D}\x{8F4E}\x{8F57}\x{8F5C}\x{8F5F}' - . '\x{8F61}\x{8F62}\x{8F63}\x{8F64}\x{8F9B}\x{8F9C}\x{8F9E}\x{8F9F}\x{8FA3}' - . '\x{8FA7}\x{8FA8}\x{8FAD}\x{8FAE}\x{8FAF}\x{8FB0}\x{8FB1}\x{8FB2}\x{8FB7}' - . '\x{8FBA}\x{8FBB}\x{8FBC}\x{8FBF}\x{8FC2}\x{8FC4}\x{8FC5}\x{8FCE}\x{8FD1}' - . '\x{8FD4}\x{8FDA}\x{8FE2}\x{8FE5}\x{8FE6}\x{8FE9}\x{8FEA}\x{8FEB}\x{8FED}' - . '\x{8FEF}\x{8FF0}\x{8FF4}\x{8FF7}\x{8FF8}\x{8FF9}\x{8FFA}\x{8FFD}\x{9000}' - . '\x{9001}\x{9003}\x{9005}\x{9006}\x{900B}\x{900D}\x{900E}\x{900F}\x{9010}' - . '\x{9011}\x{9013}\x{9014}\x{9015}\x{9016}\x{9017}\x{9019}\x{901A}\x{901D}' - . '\x{901E}\x{901F}\x{9020}\x{9021}\x{9022}\x{9023}\x{9027}\x{902E}\x{9031}' - . '\x{9032}\x{9035}\x{9036}\x{9038}\x{9039}\x{903C}\x{903E}\x{9041}\x{9042}' - . '\x{9045}\x{9047}\x{9049}\x{904A}\x{904B}\x{904D}\x{904E}\x{904F}\x{9050}' - . '\x{9051}\x{9052}\x{9053}\x{9054}\x{9055}\x{9056}\x{9058}\x{9059}\x{905C}' - . '\x{905E}\x{9060}\x{9061}\x{9063}\x{9065}\x{9068}\x{9069}\x{906D}\x{906E}' - . '\x{906F}\x{9072}\x{9075}\x{9076}\x{9077}\x{9078}\x{907A}\x{907C}\x{907D}' - . '\x{907F}\x{9080}\x{9081}\x{9082}\x{9083}\x{9084}\x{9087}\x{9089}\x{908A}' - . '\x{908F}\x{9091}\x{90A3}\x{90A6}\x{90A8}\x{90AA}\x{90AF}\x{90B1}\x{90B5}' - . '\x{90B8}\x{90C1}\x{90CA}\x{90CE}\x{90DB}\x{90E1}\x{90E2}\x{90E4}\x{90E8}' - . '\x{90ED}\x{90F5}\x{90F7}\x{90FD}\x{9102}\x{9112}\x{9119}\x{912D}\x{9130}' - . '\x{9132}\x{9149}\x{914A}\x{914B}\x{914C}\x{914D}\x{914E}\x{9152}\x{9154}' - . '\x{9156}\x{9158}\x{9162}\x{9163}\x{9165}\x{9169}\x{916A}\x{916C}\x{9172}' - . '\x{9173}\x{9175}\x{9177}\x{9178}\x{9182}\x{9187}\x{9189}\x{918B}\x{918D}' - . '\x{9190}\x{9192}\x{9197}\x{919C}\x{91A2}\x{91A4}\x{91AA}\x{91AB}\x{91AF}' - . '\x{91B4}\x{91B5}\x{91B8}\x{91BA}\x{91C0}\x{91C1}\x{91C6}\x{91C7}\x{91C8}' - . '\x{91C9}\x{91CB}\x{91CC}\x{91CD}\x{91CE}\x{91CF}\x{91D0}\x{91D1}\x{91D6}' - . '\x{91D8}\x{91DB}\x{91DC}\x{91DD}\x{91DF}\x{91E1}\x{91E3}\x{91E6}\x{91E7}' - . '\x{91F5}\x{91F6}\x{91FC}\x{91FF}\x{920D}\x{920E}\x{9211}\x{9214}\x{9215}' - . '\x{921E}\x{9229}\x{922C}\x{9234}\x{9237}\x{923F}\x{9244}\x{9245}\x{9248}' - . '\x{9249}\x{924B}\x{9250}\x{9257}\x{925A}\x{925B}\x{925E}\x{9262}\x{9264}' - . '\x{9266}\x{9271}\x{927E}\x{9280}\x{9283}\x{9285}\x{9291}\x{9293}\x{9295}' - . '\x{9296}\x{9298}\x{929A}\x{929B}\x{929C}\x{92AD}\x{92B7}\x{92B9}\x{92CF}' - . '\x{92D2}\x{92E4}\x{92E9}\x{92EA}\x{92ED}\x{92F2}\x{92F3}\x{92F8}\x{92FA}' - . '\x{92FC}\x{9306}\x{930F}\x{9310}\x{9318}\x{9319}\x{931A}\x{9320}\x{9322}' - . '\x{9323}\x{9326}\x{9328}\x{932B}\x{932C}\x{932E}\x{932F}\x{9332}\x{9335}' - . '\x{933A}\x{933B}\x{9344}\x{934B}\x{934D}\x{9354}\x{9356}\x{935B}\x{935C}' - . '\x{9360}\x{936C}\x{936E}\x{9375}\x{937C}\x{937E}\x{938C}\x{9394}\x{9396}' - . '\x{9397}\x{939A}\x{93A7}\x{93AC}\x{93AD}\x{93AE}\x{93B0}\x{93B9}\x{93C3}' - . '\x{93C8}\x{93D0}\x{93D1}\x{93D6}\x{93D7}\x{93D8}\x{93DD}\x{93E1}\x{93E4}' - . '\x{93E5}\x{93E8}\x{9403}\x{9407}\x{9410}\x{9413}\x{9414}\x{9418}\x{9419}' - . '\x{941A}\x{9421}\x{942B}\x{9435}\x{9436}\x{9438}\x{943A}\x{9441}\x{9444}' - . '\x{9451}\x{9452}\x{9453}\x{945A}\x{945B}\x{945E}\x{9460}\x{9462}\x{946A}' - . '\x{9470}\x{9475}\x{9477}\x{947C}\x{947D}\x{947E}\x{947F}\x{9481}\x{9577}' - . '\x{9580}\x{9582}\x{9583}\x{9587}\x{9589}\x{958A}\x{958B}\x{958F}\x{9591}' - . '\x{9593}\x{9594}\x{9596}\x{9598}\x{9599}\x{95A0}\x{95A2}\x{95A3}\x{95A4}' - . '\x{95A5}\x{95A7}\x{95A8}\x{95AD}\x{95B2}\x{95B9}\x{95BB}\x{95BC}\x{95BE}' - . '\x{95C3}\x{95C7}\x{95CA}\x{95CC}\x{95CD}\x{95D4}\x{95D5}\x{95D6}\x{95D8}' - . '\x{95DC}\x{95E1}\x{95E2}\x{95E5}\x{961C}\x{9621}\x{9628}\x{962A}\x{962E}' - . '\x{962F}\x{9632}\x{963B}\x{963F}\x{9640}\x{9642}\x{9644}\x{964B}\x{964C}' - . '\x{964D}\x{964F}\x{9650}\x{965B}\x{965C}\x{965D}\x{965E}\x{965F}\x{9662}' - . '\x{9663}\x{9664}\x{9665}\x{9666}\x{966A}\x{966C}\x{9670}\x{9672}\x{9673}' - . '\x{9675}\x{9676}\x{9677}\x{9678}\x{967A}\x{967D}\x{9685}\x{9686}\x{9688}' - . '\x{968A}\x{968B}\x{968D}\x{968E}\x{968F}\x{9694}\x{9695}\x{9697}\x{9698}' - . '\x{9699}\x{969B}\x{969C}\x{96A0}\x{96A3}\x{96A7}\x{96A8}\x{96AA}\x{96B0}' - . '\x{96B1}\x{96B2}\x{96B4}\x{96B6}\x{96B7}\x{96B8}\x{96B9}\x{96BB}\x{96BC}' - . '\x{96C0}\x{96C1}\x{96C4}\x{96C5}\x{96C6}\x{96C7}\x{96C9}\x{96CB}\x{96CC}' - . '\x{96CD}\x{96CE}\x{96D1}\x{96D5}\x{96D6}\x{96D9}\x{96DB}\x{96DC}\x{96E2}' - . '\x{96E3}\x{96E8}\x{96EA}\x{96EB}\x{96F0}\x{96F2}\x{96F6}\x{96F7}\x{96F9}' - . '\x{96FB}\x{9700}\x{9704}\x{9706}\x{9707}\x{9708}\x{970A}\x{970D}\x{970E}' - . '\x{970F}\x{9711}\x{9713}\x{9716}\x{9719}\x{971C}\x{971E}\x{9724}\x{9727}' - . '\x{972A}\x{9730}\x{9732}\x{9738}\x{9739}\x{973D}\x{973E}\x{9742}\x{9744}' - . '\x{9746}\x{9748}\x{9749}\x{9752}\x{9756}\x{9759}\x{975C}\x{975E}\x{9760}' - . '\x{9761}\x{9762}\x{9764}\x{9766}\x{9768}\x{9769}\x{976B}\x{976D}\x{9771}' - . '\x{9774}\x{9779}\x{977A}\x{977C}\x{9781}\x{9784}\x{9785}\x{9786}\x{978B}' - . '\x{978D}\x{978F}\x{9790}\x{9798}\x{979C}\x{97A0}\x{97A3}\x{97A6}\x{97A8}' - . '\x{97AB}\x{97AD}\x{97B3}\x{97B4}\x{97C3}\x{97C6}\x{97C8}\x{97CB}\x{97D3}' - . '\x{97DC}\x{97ED}\x{97EE}\x{97F2}\x{97F3}\x{97F5}\x{97F6}\x{97FB}\x{97FF}' - . '\x{9801}\x{9802}\x{9803}\x{9805}\x{9806}\x{9808}\x{980C}\x{980F}\x{9810}' - . '\x{9811}\x{9812}\x{9813}\x{9817}\x{9818}\x{981A}\x{9821}\x{9824}\x{982C}' - . '\x{982D}\x{9834}\x{9837}\x{9838}\x{983B}\x{983C}\x{983D}\x{9846}\x{984B}' - . '\x{984C}\x{984D}\x{984E}\x{984F}\x{9854}\x{9855}\x{9858}\x{985B}\x{985E}' - . '\x{9867}\x{986B}\x{986F}\x{9870}\x{9871}\x{9873}\x{9874}\x{98A8}\x{98AA}' - . '\x{98AF}\x{98B1}\x{98B6}\x{98C3}\x{98C4}\x{98C6}\x{98DB}\x{98DC}\x{98DF}' - . '\x{98E2}\x{98E9}\x{98EB}\x{98ED}\x{98EE}\x{98EF}\x{98F2}\x{98F4}\x{98FC}' - . '\x{98FD}\x{98FE}\x{9903}\x{9905}\x{9909}\x{990A}\x{990C}\x{9910}\x{9912}' - . '\x{9913}\x{9914}\x{9918}\x{991D}\x{991E}\x{9920}\x{9921}\x{9924}\x{9928}' - . '\x{992C}\x{992E}\x{993D}\x{993E}\x{9942}\x{9945}\x{9949}\x{994B}\x{994C}' - . '\x{9950}\x{9951}\x{9952}\x{9955}\x{9957}\x{9996}\x{9997}\x{9998}\x{9999}' - . '\x{99A5}\x{99A8}\x{99AC}\x{99AD}\x{99AE}\x{99B3}\x{99B4}\x{99BC}\x{99C1}' - . '\x{99C4}\x{99C5}\x{99C6}\x{99C8}\x{99D0}\x{99D1}\x{99D2}\x{99D5}\x{99D8}' - . '\x{99DB}\x{99DD}\x{99DF}\x{99E2}\x{99ED}\x{99EE}\x{99F1}\x{99F2}\x{99F8}' - . '\x{99FB}\x{99FF}\x{9A01}\x{9A05}\x{9A0E}\x{9A0F}\x{9A12}\x{9A13}\x{9A19}' - . '\x{9A28}\x{9A2B}\x{9A30}\x{9A37}\x{9A3E}\x{9A40}\x{9A42}\x{9A43}\x{9A45}' - . '\x{9A4D}\x{9A55}\x{9A57}\x{9A5A}\x{9A5B}\x{9A5F}\x{9A62}\x{9A64}\x{9A65}' - . '\x{9A69}\x{9A6A}\x{9A6B}\x{9AA8}\x{9AAD}\x{9AB0}\x{9AB8}\x{9ABC}\x{9AC0}' - . '\x{9AC4}\x{9ACF}\x{9AD1}\x{9AD3}\x{9AD4}\x{9AD8}\x{9ADE}\x{9ADF}\x{9AE2}' - . '\x{9AE3}\x{9AE6}\x{9AEA}\x{9AEB}\x{9AED}\x{9AEE}\x{9AEF}\x{9AF1}\x{9AF4}' - . '\x{9AF7}\x{9AFB}\x{9B06}\x{9B18}\x{9B1A}\x{9B1F}\x{9B22}\x{9B23}\x{9B25}' - . '\x{9B27}\x{9B28}\x{9B29}\x{9B2A}\x{9B2E}\x{9B2F}\x{9B31}\x{9B32}\x{9B3B}' - . '\x{9B3C}\x{9B41}\x{9B42}\x{9B43}\x{9B44}\x{9B45}\x{9B4D}\x{9B4E}\x{9B4F}' - . '\x{9B51}\x{9B54}\x{9B58}\x{9B5A}\x{9B6F}\x{9B74}\x{9B83}\x{9B8E}\x{9B91}' - . '\x{9B92}\x{9B93}\x{9B96}\x{9B97}\x{9B9F}\x{9BA0}\x{9BA8}\x{9BAA}\x{9BAB}' - . '\x{9BAD}\x{9BAE}\x{9BB4}\x{9BB9}\x{9BC0}\x{9BC6}\x{9BC9}\x{9BCA}\x{9BCF}' - . '\x{9BD1}\x{9BD2}\x{9BD4}\x{9BD6}\x{9BDB}\x{9BE1}\x{9BE2}\x{9BE3}\x{9BE4}' - . '\x{9BE8}\x{9BF0}\x{9BF1}\x{9BF2}\x{9BF5}\x{9C04}\x{9C06}\x{9C08}\x{9C09}' - . '\x{9C0A}\x{9C0C}\x{9C0D}\x{9C10}\x{9C12}\x{9C13}\x{9C14}\x{9C15}\x{9C1B}' - . '\x{9C21}\x{9C24}\x{9C25}\x{9C2D}\x{9C2E}\x{9C2F}\x{9C30}\x{9C32}\x{9C39}' - . '\x{9C3A}\x{9C3B}\x{9C3E}\x{9C46}\x{9C47}\x{9C48}\x{9C52}\x{9C57}\x{9C5A}' - . '\x{9C60}\x{9C67}\x{9C76}\x{9C78}\x{9CE5}\x{9CE7}\x{9CE9}\x{9CEB}\x{9CEC}' - . '\x{9CF0}\x{9CF3}\x{9CF4}\x{9CF6}\x{9D03}\x{9D06}\x{9D07}\x{9D08}\x{9D09}' - . '\x{9D0E}\x{9D12}\x{9D15}\x{9D1B}\x{9D1F}\x{9D23}\x{9D26}\x{9D28}\x{9D2A}' - . '\x{9D2B}\x{9D2C}\x{9D3B}\x{9D3E}\x{9D3F}\x{9D41}\x{9D44}\x{9D46}\x{9D48}' - . '\x{9D50}\x{9D51}\x{9D59}\x{9D5C}\x{9D5D}\x{9D5E}\x{9D60}\x{9D61}\x{9D64}' - . '\x{9D6C}\x{9D6F}\x{9D72}\x{9D7A}\x{9D87}\x{9D89}\x{9D8F}\x{9D9A}\x{9DA4}' - . '\x{9DA9}\x{9DAB}\x{9DAF}\x{9DB2}\x{9DB4}\x{9DB8}\x{9DBA}\x{9DBB}\x{9DC1}' - . '\x{9DC2}\x{9DC4}\x{9DC6}\x{9DCF}\x{9DD3}\x{9DD9}\x{9DE6}\x{9DED}\x{9DEF}' - . '\x{9DF2}\x{9DF8}\x{9DF9}\x{9DFA}\x{9DFD}\x{9E1A}\x{9E1B}\x{9E1E}\x{9E75}' - . '\x{9E78}\x{9E79}\x{9E7D}\x{9E7F}\x{9E81}\x{9E88}\x{9E8B}\x{9E8C}\x{9E91}' - . '\x{9E92}\x{9E93}\x{9E95}\x{9E97}\x{9E9D}\x{9E9F}\x{9EA5}\x{9EA6}\x{9EA9}' - . '\x{9EAA}\x{9EAD}\x{9EB8}\x{9EB9}\x{9EBA}\x{9EBB}\x{9EBC}\x{9EBE}\x{9EBF}' - . '\x{9EC4}\x{9ECC}\x{9ECD}\x{9ECE}\x{9ECF}\x{9ED0}\x{9ED2}\x{9ED4}\x{9ED8}' - . '\x{9ED9}\x{9EDB}\x{9EDC}\x{9EDD}\x{9EDE}\x{9EE0}\x{9EE5}\x{9EE8}\x{9EEF}' - . '\x{9EF4}\x{9EF6}\x{9EF7}\x{9EF9}\x{9EFB}\x{9EFC}\x{9EFD}\x{9F07}\x{9F08}' - . '\x{9F0E}\x{9F13}\x{9F15}\x{9F20}\x{9F21}\x{9F2C}\x{9F3B}\x{9F3E}\x{9F4A}' - . '\x{9F4B}\x{9F4E}\x{9F4F}\x{9F52}\x{9F54}\x{9F5F}\x{9F60}\x{9F61}\x{9F62}' - . '\x{9F63}\x{9F66}\x{9F67}\x{9F6A}\x{9F6C}\x{9F72}\x{9F76}\x{9F77}\x{9F8D}' - . '\x{9F95}\x{9F9C}\x{9F9D}\x{9FA0}]{1,15}$/iu', -]; diff --git a/lib/laminas/laminas-validator/src/Iban.php b/lib/laminas/laminas-validator/src/Iban.php deleted file mode 100644 index 65f23054f..000000000 --- a/lib/laminas/laminas-validator/src/Iban.php +++ /dev/null @@ -1,364 +0,0 @@ - - */ - protected $messageTemplates = [ - self::NOTSUPPORTED => 'Unknown country within the IBAN', - self::SEPANOTSUPPORTED => 'Countries outside the Single Euro Payments Area (SEPA) are not supported', - self::FALSEFORMAT => 'The input has a false IBAN format', - self::CHECKFAILED => 'The input has failed the IBAN check', - ]; - - /** - * Optional country code by ISO 3166-1 - * - * @var string|null - */ - protected $countryCode; - - /** - * Optionally allow IBAN codes from non-SEPA countries. Defaults to true - * - * @var bool - */ - protected $allowNonSepa = true; - - /** - * The SEPA country codes - * - * @var string[] ISO 3166-1 codes - */ - protected static $sepaCountries = [ - 'AT', - 'BE', - 'BG', - 'CY', - 'CZ', - 'DK', - 'FO', - 'GL', - 'EE', - 'FI', - 'FR', - 'DE', - 'GI', - 'GR', - 'HU', - 'IS', - 'IE', - 'IT', - 'LV', - 'LI', - 'LT', - 'LU', - 'MT', - 'MC', - 'NL', - 'NO', - 'PL', - 'PT', - 'RO', - 'SK', - 'SI', - 'ES', - 'SE', - 'CH', - 'GB', - 'SM', - 'HR', - ]; - - /** - * IBAN regexes by country code - * - * @var array - */ - protected static $ibanRegex = [ - 'AD' => 'AD[0-9]{2}[0-9]{4}[0-9]{4}[A-Z0-9]{12}', - 'AE' => 'AE[0-9]{2}[0-9]{3}[0-9]{16}', - 'AL' => 'AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}', - 'AT' => 'AT[0-9]{2}[0-9]{5}[0-9]{11}', - 'AZ' => 'AZ[0-9]{2}[A-Z]{4}[A-Z0-9]{20}', - 'BA' => 'BA[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{8}[0-9]{2}', - 'BE' => 'BE[0-9]{2}[0-9]{3}[0-9]{7}[0-9]{2}', - 'BG' => 'BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}', - 'BH' => 'BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}', - 'BR' => 'BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z][A-Z0-9]', - 'BY' => 'BY[0-9]{2}[A-Z0-9]{4}[0-9]{4}[A-Z0-9]{16}', - 'CH' => 'CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}', - 'CR' => 'CR[0-9]{2}[0-9]{3}[0-9]{14}', - 'CY' => 'CY[0-9]{2}[0-9]{3}[0-9]{5}[A-Z0-9]{16}', - 'CZ' => 'CZ[0-9]{2}[0-9]{20}', - 'DE' => 'DE[0-9]{2}[0-9]{8}[0-9]{10}', - 'DO' => 'DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}', - 'DK' => 'DK[0-9]{2}[0-9]{14}', - 'EE' => 'EE[0-9]{2}[0-9]{2}[0-9]{2}[0-9]{11}[0-9]{1}', - 'ES' => 'ES[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{1}[0-9]{1}[0-9]{10}', - 'FI' => 'FI[0-9]{2}[0-9]{6}[0-9]{7}[0-9]{1}', - 'FO' => 'FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}', - 'FR' => 'FR[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}', - 'GB' => 'GB[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}', - 'GE' => 'GE[0-9]{2}[A-Z]{2}[0-9]{16}', - 'GI' => 'GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}', - 'GL' => 'GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}', - 'GR' => 'GR[0-9]{2}[0-9]{3}[0-9]{4}[A-Z0-9]{16}', - 'GT' => 'GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}', - 'HR' => 'HR[0-9]{2}[0-9]{7}[0-9]{10}', - 'HU' => 'HU[0-9]{2}[0-9]{3}[0-9]{4}[0-9]{1}[0-9]{15}[0-9]{1}', - 'IE' => 'IE[0-9]{2}[A-Z]{4}[0-9]{6}[0-9]{8}', - 'IL' => 'IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}', - 'IS' => 'IS[0-9]{2}[0-9]{4}[0-9]{2}[0-9]{6}[0-9]{10}', - 'IT' => 'IT[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}', - 'KW' => 'KW[0-9]{2}[A-Z]{4}[0-9]{22}', - 'KZ' => 'KZ[0-9]{2}[0-9]{3}[A-Z0-9]{13}', - 'LB' => 'LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}', - 'LI' => 'LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}', - 'LT' => 'LT[0-9]{2}[0-9]{5}[0-9]{11}', - 'LU' => 'LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}', - 'LV' => 'LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}', - 'MC' => 'MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}', - 'MD' => 'MD[0-9]{2}[A-Z0-9]{20}', - 'ME' => 'ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', - 'MK' => 'MK[0-9]{2}[0-9]{3}[A-Z0-9]{10}[0-9]{2}', - 'MR' => 'MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}', - 'MT' => 'MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}', - 'MU' => 'MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{3}', - 'NL' => 'NL[0-9]{2}[A-Z]{4}[0-9]{10}', - 'NO' => 'NO[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{1}', - 'UA' => 'UA[0-9]{2}[0-9]{6}[0-9]{19}', - 'PK' => 'PK[0-9]{2}[A-Z]{4}[A-Z0-9]{16}', - 'PL' => 'PL[0-9]{2}[0-9]{8}[0-9]{16}', - 'PS' => 'PS[0-9]{2}[A-Z]{4}[A-Z0-9]{21}', - 'PT' => 'PT[0-9]{2}[0-9]{4}[0-9]{4}[0-9]{11}[0-9]{2}', - 'RO' => 'RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}', - 'RS' => 'RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', - 'SA' => 'SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}', - 'SE' => 'SE[0-9]{2}[0-9]{3}[0-9]{16}[0-9]{1}', - 'SI' => 'SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}', - 'SK' => 'SK[0-9]{2}[0-9]{4}[0-9]{6}[0-9]{10}', - 'SM' => 'SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}', - 'TN' => 'TN59[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}', - 'TR' => 'TR[0-9]{2}[0-9]{5}[A-Z0-9]{1}[A-Z0-9]{16}', - 'VG' => 'VG[0-9]{2}[A-Z]{4}[0-9]{16}', - ]; - - /** - * Sets validator options - * - * @param array|Traversable $options OPTIONAL - */ - public function __construct($options = []) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - - if (array_key_exists('country_code', $options)) { - $this->setCountryCode($options['country_code']); - } - - if (array_key_exists('allow_non_sepa', $options)) { - $this->setAllowNonSepa($options['allow_non_sepa']); - } - - parent::__construct($options); - } - - /** - * Returns the optional country code by ISO 3166-1 - * - * @return string|null - */ - public function getCountryCode() - { - return $this->countryCode; - } - - /** - * Sets an optional country code by ISO 3166-1 - * - * @param string|null $countryCode - * @return $this provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function setCountryCode($countryCode = null) - { - if ($countryCode !== null) { - $countryCode = (string) $countryCode; - - if (! isset(static::$ibanRegex[$countryCode])) { - throw new Exception\InvalidArgumentException( - "Country code '{$countryCode}' invalid by ISO 3166-1 or not supported" - ); - } - } - - $this->countryCode = $countryCode; - return $this; - } - - /** - * Returns the optional allow non-sepa countries setting - * - * @return bool - */ - public function allowNonSepa() - { - return $this->allowNonSepa; - } - - /** - * Sets the optional allow non-sepa countries setting - * - * @param bool $allowNonSepa - * @return $this provides a fluent interface - */ - public function setAllowNonSepa($allowNonSepa) - { - $this->allowNonSepa = (bool) $allowNonSepa; - return $this; - } - - /** - * Returns true if $value is a valid IBAN - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::FALSEFORMAT); - return false; - } - - $value = str_replace(' ', '', strtoupper($value)); - $this->setValue($value); - - $countryCode = $this->getCountryCode(); - if ($countryCode === null) { - $countryCode = substr($value, 0, 2); - } - - if (! array_key_exists($countryCode, static::$ibanRegex)) { - $this->setValue($countryCode); - $this->error(self::NOTSUPPORTED); - return false; - } - - if (! $this->allowNonSepa && ! in_array($countryCode, static::$sepaCountries)) { - $this->setValue($countryCode); - $this->error(self::SEPANOTSUPPORTED); - return false; - } - - if (! preg_match('/^' . static::$ibanRegex[$countryCode] . '$/', $value)) { - $this->error(self::FALSEFORMAT); - return false; - } - - $format = substr($value, 4) . substr($value, 0, 4); - $format = str_replace( - [ - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', - 'Y', - 'Z', - ], - [ - '10', - '11', - '12', - '13', - '14', - '15', - '16', - '17', - '18', - '19', - '20', - '21', - '22', - '23', - '24', - '25', - '26', - '27', - '28', - '29', - '30', - '31', - '32', - '33', - '34', - '35', - ], - $format - ); - - $temp = intval(substr($format, 0, 1)); - $len = strlen($format); - for ($x = 1; $x < $len; ++$x) { - $temp *= 10; - $temp += intval(substr($format, $x, 1)); - $temp %= 97; - } - - if ($temp !== 1) { - $this->error(self::CHECKFAILED); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Identical.php b/lib/laminas/laminas-validator/src/Identical.php deleted file mode 100644 index ef766941d..000000000 --- a/lib/laminas/laminas-validator/src/Identical.php +++ /dev/null @@ -1,218 +0,0 @@ - 'The two given tokens do not match', - self::MISSING_TOKEN => 'No token was provided to match against', - ]; - - /** @var array */ - protected $messageVariables = [ - 'token' => 'tokenString', - ]; - - /** - * Original token against which to validate - * - * @var null|string - */ - protected $tokenString; - - /** @var null|string */ - protected $token; - - /** @var bool */ - protected $strict = true; - - /** @var bool */ - protected $literal = false; - - /** - * Sets validator options - * - * @param mixed $token - */ - public function __construct($token = null) - { - if ($token instanceof Traversable) { - $token = ArrayUtils::iteratorToArray($token); - } - - if (is_array($token) && array_key_exists('token', $token)) { - if (array_key_exists('strict', $token)) { - $this->setStrict($token['strict']); - } - - if (array_key_exists('literal', $token)) { - $this->setLiteral($token['literal']); - } - - $this->setToken($token['token']); - } elseif (null !== $token) { - $this->setToken($token); - } - - parent::__construct(is_array($token) ? $token : null); - } - - /** - * Retrieve token - * - * @return mixed - */ - public function getToken() - { - return $this->token; - } - - /** - * Set token against which to compare - * - * @return $this - */ - public function setToken(mixed $token) - { - $this->tokenString = is_array($token) ? var_export($token, true) : (string) $token; - $this->token = $token; - return $this; - } - - /** - * Returns the strict parameter - * - * @return bool - */ - public function getStrict() - { - return $this->strict; - } - - /** - * Sets the strict parameter - * - * @param bool $strict - * @return $this - */ - public function setStrict($strict) - { - $this->strict = (bool) $strict; - return $this; - } - - /** - * Returns the literal parameter - * - * @return bool - */ - public function getLiteral() - { - return $this->literal; - } - - /** - * Sets the literal parameter - * - * @param bool $literal - * @return $this - */ - public function setLiteral($literal) - { - $this->literal = (bool) $literal; - return $this; - } - - /** - * Returns true if and only if a token has been set and the provided value - * matches that token. - * - * @param mixed $value - * @param null|array|ArrayAccess $context - * @throws Exception\InvalidArgumentException If context is not array or ArrayObject. - * @return bool - */ - public function isValid($value, $context = null) - { - $this->setValue($value); - - $token = $this->getToken(); - - if (! $this->getLiteral() && $context !== null) { - if (! is_array($context) && ! $context instanceof ArrayAccess) { - throw new Exception\InvalidArgumentException(sprintf( - 'Context passed to %s must be array, ArrayObject or null; received "%s"', - __METHOD__, - get_debug_type($context) - )); - } - - if (is_array($token)) { - while (is_array($token)) { - $key = key($token); - if (! isset($context[$key])) { - break; - } - $context = $context[$key]; - $token = $token[$key]; - } - } - - // if $token is an array it means the above loop didn't went all the way down to the leaf, - // so the $token structure doesn't match the $context structure - if ( - is_array($token) - || (! is_int($token) && ! is_string($token)) - || ! isset($context[$token]) - ) { - $token = $this->getToken(); - } else { - $token = $context[$token]; - } - } - - if ($token === null) { - $this->error(self::MISSING_TOKEN); - return false; - } - - $strict = $this->getStrict(); - if ( - ($strict && ($value !== $token)) - // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator - || (! $strict && ($value != $token)) - ) { - $this->error(self::NOT_SAME); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/InArray.php b/lib/laminas/laminas-validator/src/InArray.php deleted file mode 100644 index e1289c4cc..000000000 --- a/lib/laminas/laminas-validator/src/InArray.php +++ /dev/null @@ -1,253 +0,0 @@ - */ - protected $messageTemplates = [ - self::NOT_IN_ARRAY => 'The input was not found in the haystack', - ]; - - /** - * Haystack of possible values - * - * @var array - */ - protected $haystack; - - /** - * Type of strict check to be used. Due to "foo" == 0 === TRUE with in_array when strict = false, - * an option has been added to prevent this. When $strict = 0/false, the most - * secure non-strict check is implemented. if $strict = -1, the default in_array non-strict - * behaviour is used - * - * @var int - */ - protected $strict = self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY; - - /** - * Whether a recursive search should be done - * - * @var bool - */ - protected $recursive = false; - - /** - * Returns the haystack option - * - * @return mixed - * @throws Exception\RuntimeException If haystack option is not set. - */ - public function getHaystack() - { - if ($this->haystack === null) { - throw new Exception\RuntimeException('haystack option is mandatory'); - } - return $this->haystack; - } - - /** - * Sets the haystack option - * - * @param mixed $haystack - * @return $this Provides a fluent interface - */ - public function setHaystack(array $haystack) - { - $this->haystack = $haystack; - return $this; - } - - /** - * Returns the strict option - * - * @return bool|int - */ - public function getStrict() - { - // To keep BC with new strict modes - if ( - $this->strict === self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY - || $this->strict === self::COMPARE_STRICT - ) { - return (bool) $this->strict; - } - return $this->strict; - } - - /** - * Sets the strict option mode - * InArray::COMPARE_STRICT - * InArray::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY - * InArray::COMPARE_NOT_STRICT - * - * @param int|bool $strict - * @return $this Provides a fluent interface - * @throws Exception\InvalidArgumentException - */ - public function setStrict($strict) - { - if (is_bool($strict)) { - $strict = $strict ? self::COMPARE_STRICT : self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY; - } - - $checkTypes = [ - self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY, // 0 - self::COMPARE_STRICT, // 1 - self::COMPARE_NOT_STRICT, // -1 - ]; - - // validate strict value - if (! in_array($strict, $checkTypes)) { - throw new Exception\InvalidArgumentException('Strict option must be one of the COMPARE_ constants'); - } - - $this->strict = $strict; - return $this; - } - - /** - * Returns the recursive option - * - * @return bool - */ - public function getRecursive() - { - return $this->recursive; - } - - /** - * Sets the recursive option - * - * @param bool $recursive - * @return $this Provides a fluent interface - */ - public function setRecursive($recursive) - { - $this->recursive = (bool) $recursive; - return $this; - } - - /** - * Returns true if and only if $value is contained in the haystack option. If the strict - * option is true, then the type of $value is also checked. - * - * @param mixed $value - * See {@link http://php.net/manual/function.in-array.php#104501} - * @return bool - */ - public function isValid($value) - { - // we create a copy of the haystack in case we need to modify it - $haystack = $this->getHaystack(); - - // if the input is a string or float, and vulnerability protection is on - // we type cast the input to a string - if ( - self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY === $this->strict - && (is_int($value) || is_float($value)) - ) { - $value = (string) $value; - } - - $this->setValue($value); - - if ($this->getRecursive()) { - $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack)); - foreach ($iterator as $element) { - if (self::COMPARE_STRICT === $this->strict) { - if ($element === $value) { - return true; - } - - continue; - } - - // add protection to prevent string to int vuln's - $el = $element; - if ( - self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY === $this->strict - && is_string($value) && (is_int($el) || is_float($el)) - ) { - $el = (string) $el; - } - - // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator - if ($el == $value) { - return true; - } - } - - $this->error(self::NOT_IN_ARRAY); - return false; - } - - /** - * If the check is not strict, then, to prevent "asdf" being converted to 0 - * and returning a false positive if 0 is in haystack, we type cast - * the haystack to strings. To prevent "56asdf" == 56 === TRUE we also - * type cast values like 56 to strings as well. - * - * This occurs only if the input is a string and a haystack member is an int - */ - if ( - self::COMPARE_NOT_STRICT_AND_PREVENT_STR_TO_INT_VULNERABILITY === $this->strict - && is_string($value) - ) { - foreach ($haystack as &$h) { - if (is_int($h) || is_float($h)) { - $h = (string) $h; - } - } - - if (in_array($value, $haystack, (bool) $this->strict)) { - return true; - } - - $this->error(self::NOT_IN_ARRAY); - return false; - } - - if (in_array($value, $haystack, self::COMPARE_STRICT === $this->strict)) { - return true; - } - - if (self::COMPARE_NOT_STRICT === $this->strict) { - return true; - } - - $this->error(self::NOT_IN_ARRAY); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/Ip.php b/lib/laminas/laminas-validator/src/Ip.php deleted file mode 100644 index 903da7f63..000000000 --- a/lib/laminas/laminas-validator/src/Ip.php +++ /dev/null @@ -1,194 +0,0 @@ - 'Invalid type given. String expected', - self::NOT_IP_ADDRESS => 'The input does not appear to be a valid IP address', - ]; - - /** - * Internal options - * - * @var array - */ - protected $options = [ - 'allowipv4' => true, // Enable IPv4 Validation - 'allowipv6' => true, // Enable IPv6 Validation - 'allowipvfuture' => false, // Enable IPvFuture Validation - 'allowliteral' => true, // Enable IPs in literal format (only IPv6 and IPvFuture) - ]; - - /** - * Sets the options for this validator - * - * @param array|Traversable $options - * @throws Exception\InvalidArgumentException If there is any kind of IP allowed or $options is not an array - * or Traversable. - * @return AbstractValidator - */ - public function setOptions($options = []) - { - parent::setOptions($options); - - if (! $this->options['allowipv4'] && ! $this->options['allowipv6'] && ! $this->options['allowipvfuture']) { - throw new Exception\InvalidArgumentException('Nothing to validate. Check your options'); - } - - return $this; - } - - /** - * Returns true if and only if $value is a valid IP address - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - - if ($this->options['allowipv4'] && $this->validateIPv4($value)) { - return true; - } else { - if ((bool) $this->options['allowliteral']) { - static $regex = '/^\[(.*)\]$/'; - if ((bool) preg_match($regex, $value, $matches)) { - $value = $matches[1]; - } - } - - if ( - ($this->options['allowipv6'] && $this->validateIPv6($value)) || - ($this->options['allowipvfuture'] && $this->validateIPvFuture($value)) - ) { - return true; - } - } - $this->error(self::NOT_IP_ADDRESS); - return false; - } - - /** - * Validates an IPv4 address - * - * @param string $value - * @return bool - */ - protected function validateIPv4($value) - { - if (preg_match('/^([01]{8}\.){3}[01]{8}\z/i', $value)) { - // binary format 00000000.00000000.00000000.00000000 - $value = bindec(substr($value, 0, 8)) . '.' . bindec(substr($value, 9, 8)) . '.' - . bindec(substr($value, 18, 8)) . '.' . bindec(substr($value, 27, 8)); - } elseif (preg_match('/^([0-9]{3}\.){3}[0-9]{3}\z/i', $value)) { - // octet format 777.777.777.777 - $value = (int) substr($value, 0, 3) . '.' . (int) substr($value, 4, 3) . '.' - . (int) substr($value, 8, 3) . '.' . (int) substr($value, 12, 3); - } elseif (preg_match('/^([0-9a-f]{2}\.){3}[0-9a-f]{2}\z/i', $value)) { - // hex format ff.ff.ff.ff - $value = hexdec(substr($value, 0, 2)) . '.' . hexdec(substr($value, 3, 2)) . '.' - . hexdec(substr($value, 6, 2)) . '.' . hexdec(substr($value, 9, 2)); - } - - $ip2long = ip2long($value); - if ($ip2long === false) { - return false; - } - - return $value === long2ip($ip2long); - } - - /** - * Validates an IPv6 address - * - * @param string $value Value to check against - * @return bool|int True when $value is a valid ipv6 address False otherwise - */ - protected function validateIPv6($value) - { - if (strlen($value) < 3) { - return $value === '::'; - } - - if (strpos($value, '.')) { - $lastcolon = strrpos($value, ':'); - if (! ($lastcolon && $this->validateIPv4(substr($value, $lastcolon + 1)))) { - return false; - } - - $value = substr($value, 0, $lastcolon) . ':0:0'; - } - - if (! str_contains($value, '::')) { - return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value); - } - - $colonCount = substr_count($value, ':'); - if ($colonCount < 8) { - return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value); - } - - // special case with ending or starting double colon - if ($colonCount === 8) { - return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value); - } - - return false; - } - - /** - * Validates an IPvFuture address. - * - * IPvFuture is loosely defined in the Section 3.2.2 of RFC 3986 - * - * @param string $value Value to check against - * @return bool True when $value is a valid IPvFuture address - * False otherwise - */ - protected function validateIPvFuture($value) - { - /* - * ABNF: - * IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," - * / ";" / "=" - */ - static $regex = '/^v([[:xdigit:]]+)\.[[:alnum:]\-\._~!\$&\'\(\)\*\+,;=:]+$/'; - - $result = (bool) preg_match($regex, $value, $matches); - - /* - * "As such, implementations must not provide the version flag for the - * existing IPv4 and IPv6 literal address forms described below." - */ - return $result && $matches[1] !== '4' && $matches[1] !== '6'; - } -} diff --git a/lib/laminas/laminas-validator/src/IsCountable.php b/lib/laminas/laminas-validator/src/IsCountable.php deleted file mode 100644 index 824fd3148..000000000 --- a/lib/laminas/laminas-validator/src/IsCountable.php +++ /dev/null @@ -1,200 +0,0 @@ - 'The input must be an array or an instance of \\Countable', - self::NOT_EQUALS => "The input count must equal '%count%'", - self::GREATER_THAN => "The input count must be less than '%max%', inclusively", - self::LESS_THAN => "The input count must be greater than '%min%', inclusively", - ]; - - /** - * Additional variables available for validation failure messages - * - * @var array - */ - protected $messageVariables = [ - 'count' => ['options' => 'count'], - 'min' => ['options' => 'min'], - 'max' => ['options' => 'max'], - ]; - - /** - * Options for the between validator - * - * @var array - */ - protected $options = [ - 'count' => null, - 'min' => null, - 'max' => null, - ]; - - /** - * @param array|Traversable $options - * @return $this Provides fluid interface - */ - public function setOptions($options = []) - { - foreach (['count', 'min', 'max'] as $option) { - if (! is_array($options) || ! isset($options[$option])) { - continue; - } - - $method = sprintf('set%s', ucfirst($option)); - $this->$method($options[$option]); - unset($options[$option]); - } - - return parent::setOptions($options); - } - - /** - * Returns true if and only if $value is countable (and the count validates against optional values). - * - * @param iterable $value - * @return bool - */ - public function isValid($value) - { - if (! is_countable($value)) { - $this->error(self::NOT_COUNTABLE); - return false; - } - - $count = count($value); - - if (is_numeric($this->getCount())) { - if ($count !== $this->getCount()) { - $this->error(self::NOT_EQUALS); - return false; - } - - return true; - } - - if (is_numeric($this->getMax()) && $count > $this->getMax()) { - $this->error(self::GREATER_THAN); - return false; - } - - if (is_numeric($this->getMin()) && $count < $this->getMin()) { - $this->error(self::LESS_THAN); - return false; - } - - return true; - } - - /** - * Returns the count option - * - * @return mixed - */ - public function getCount() - { - return $this->options['count']; - } - - /** - * Returns the min option - * - * @return mixed - */ - public function getMin() - { - return $this->options['min']; - } - - /** - * Returns the max option - * - * @return mixed - */ - public function getMax() - { - return $this->options['max']; - } - - /** - * @return void - * @throws Exception\InvalidArgumentException If either a min or max option - * was previously set. - */ - private function setCount(mixed $value) - { - if (isset($this->options['min']) || isset($this->options['max'])) { - throw new Exception\InvalidArgumentException( - 'Cannot set count; conflicts with either a min or max option previously set' - ); - } - $this->options['count'] = $value; - } - - /** - * @return void - * @throws Exception\InvalidArgumentException If either a count or max option - * was previously set. - */ - private function setMin(mixed $value) - { - if (isset($this->options['count'])) { - throw new Exception\InvalidArgumentException( - 'Cannot set count; conflicts with either a count option previously set' - ); - } - $this->options['min'] = $value; - } - - /** - * @return void - * @throws Exception\InvalidArgumentException If either a count or min option - * was previously set. - */ - private function setMax(mixed $value) - { - if (isset($this->options['count'])) { - throw new Exception\InvalidArgumentException( - 'Cannot set count; conflicts with either a count option previously set' - ); - } - $this->options['max'] = $value; - } -} diff --git a/lib/laminas/laminas-validator/src/IsInstanceOf.php b/lib/laminas/laminas-validator/src/IsInstanceOf.php deleted file mode 100644 index e6009afb3..000000000 --- a/lib/laminas/laminas-validator/src/IsInstanceOf.php +++ /dev/null @@ -1,103 +0,0 @@ - "The input is not an instance of '%className%'", - ]; - - /** - * Additional variables available for validation failure messages - * - * @var array - */ - protected $messageVariables = [ - 'className' => 'className', - ]; - - /** @var string */ - protected $className; - - /** - * Sets validator options - * - * @param array|Traversable $options - * @throws Exception\InvalidArgumentException - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = iterator_to_array($options); - } - - // If argument is not an array, consider first argument as class name - if (! is_array($options)) { - $options = func_get_args(); - - $tmpOptions = []; - $tmpOptions['className'] = array_shift($options); - - $options = $tmpOptions; - } - - if (! array_key_exists('className', $options)) { - throw new Exception\InvalidArgumentException('Missing option "className"'); - } - - parent::__construct($options); - } - - /** - * Get class name - * - * @return string - */ - public function getClassName() - { - return $this->className; - } - - /** - * Set class name - * - * @param string $className - * @return $this - */ - public function setClassName($className) - { - $this->className = $className; - return $this; - } - - /** - * Returns true if $value is instance of $this->className - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - if ($value instanceof $this->className) { - return true; - } - $this->error(self::NOT_INSTANCE_OF); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/Isbn.php b/lib/laminas/laminas-validator/src/Isbn.php deleted file mode 100644 index d5d11876b..000000000 --- a/lib/laminas/laminas-validator/src/Isbn.php +++ /dev/null @@ -1,189 +0,0 @@ - 'Invalid type given. String or integer expected', - self::NO_ISBN => 'The input is not a valid ISBN number', - ]; - - /** @var array */ - protected $options = [ - 'type' => self::AUTO, // Allowed type - 'separator' => '', // Separator character - ]; - - /** - * Detect input format. - * - * @return null|string - */ - protected function detectFormat() - { - // prepare separator and pattern list - $sep = quotemeta($this->getSeparator()); - $patterns = []; - $lengths = []; - $type = $this->getType(); - - // check for ISBN-10 - if ($type === self::ISBN10 || $type === self::AUTO) { - if (empty($sep)) { - $pattern = '/^[0-9]{9}[0-9X]{1}$/'; - $length = 10; - } else { - $pattern = "/^[0-9]{1,7}[{$sep}]{1}[0-9]{1,7}[{$sep}]{1}[0-9]{1,7}[{$sep}]{1}[0-9X]{1}$/"; - $length = 13; - } - - $patterns[$pattern] = self::ISBN10; - $lengths[$pattern] = $length; - } - - // check for ISBN-13 - if ($type === self::ISBN13 || $type === self::AUTO) { - if (empty($sep)) { - $pattern = '/^[0-9]{13}$/'; - $length = 13; - } else { - // @codingStandardsIgnoreStart - $pattern = "/^[0-9]{1,9}[{$sep}]{1}[0-9]{1,5}[{$sep}]{1}[0-9]{1,9}[{$sep}]{1}[0-9]{1,9}[{$sep}]{1}[0-9]{1}$/"; - // @codingStandardsIgnoreEnd - $length = 17; - } - - $patterns[$pattern] = self::ISBN13; - $lengths[$pattern] = $length; - } - - // check pattern list - foreach ($patterns as $pattern => $type) { - if ((strlen($this->getValue()) === $lengths[$pattern]) && preg_match($pattern, $this->getValue())) { - return $type; - } - } - - return null; - } - - /** - * Returns true if and only if $value is a valid ISBN. - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value) && ! is_int($value)) { - $this->error(self::INVALID); - return false; - } - - $value = (string) $value; - $this->setValue($value); - - switch ($this->detectFormat()) { - case self::ISBN10: - $isbn = new Isbn\Isbn10(); - break; - - case self::ISBN13: - $isbn = new Isbn\Isbn13(); - break; - - default: - $this->error(self::NO_ISBN); - return false; - } - - $value = str_replace($this->getSeparator(), '', $value); - $checksum = $isbn->getChecksum($value); - - // validate - if (substr($this->getValue(), -1) !== (string) $checksum) { - $this->error(self::NO_ISBN); - return false; - } - return true; - } - - /** - * Set separator characters. - * - * It is allowed only empty string, hyphen and space. - * - * @param string $separator - * @throws Exception\InvalidArgumentException When $separator is not valid. - * @return $this Provides a fluent interface - */ - public function setSeparator($separator) - { - // check separator - if (! in_array($separator, ['-', ' ', ''])) { - throw new Exception\InvalidArgumentException('Invalid ISBN separator.'); - } - - $this->options['separator'] = $separator; - return $this; - } - - /** - * Get separator characters. - * - * @return string - */ - public function getSeparator() - { - return $this->options['separator']; - } - - /** - * Set allowed ISBN type. - * - * @param string $type - * @throws Exception\InvalidArgumentException When $type is not valid. - * @return $this Provides a fluent interface - */ - public function setType($type) - { - // check type - if (! in_array($type, [self::AUTO, self::ISBN10, self::ISBN13])) { - throw new Exception\InvalidArgumentException('Invalid ISBN type'); - } - - $this->options['type'] = $type; - return $this; - } - - /** - * Get allowed ISBN type. - * - * @return string - */ - public function getType() - { - return $this->options['type']; - } -} diff --git a/lib/laminas/laminas-validator/src/Isbn/Isbn10.php b/lib/laminas/laminas-validator/src/Isbn/Isbn10.php deleted file mode 100755 index 4bcc6570d..000000000 --- a/lib/laminas/laminas-validator/src/Isbn/Isbn10.php +++ /dev/null @@ -1,54 +0,0 @@ -sum($value); - return $this->checksum($sum); - } - - /** - * Calculate the value sum. - * - * @param string $value - * @return int - */ - private function sum($value) - { - $sum = 0; - - for ($i = 0; $i < 9; $i++) { - $sum += (10 - $i) * (int) $value[$i]; - } - - return $sum; - } - - /** - * Calculate the checksum for the value's sum. - * - * @param int $sum - * @return int|string - */ - private function checksum($sum) - { - $checksum = 11 - ($sum % 11); - - if ($checksum === 11) { - return '0'; - } - - if ($checksum === 10) { - return 'X'; - } - - return $checksum; - } -} diff --git a/lib/laminas/laminas-validator/src/Isbn/Isbn13.php b/lib/laminas/laminas-validator/src/Isbn/Isbn13.php deleted file mode 100755 index c5aaf494e..000000000 --- a/lib/laminas/laminas-validator/src/Isbn/Isbn13.php +++ /dev/null @@ -1,55 +0,0 @@ -sum($value); - return $this->checksum($sum); - } - - /** - * Calculate the value sum. - * - * @param string $value - * @return int - */ - private function sum($value) - { - $sum = 0; - - for ($i = 0; $i < 12; $i++) { - if ($i % 2 === 0) { - $sum += (int) $value[$i]; - continue; - } - - $sum += 3 * (int) $value[$i]; - } - - return $sum; - } - - /** - * Calculate the checksum for the value's sum. - * - * @param int $sum - * @return int|string - */ - private function checksum($sum) - { - $checksum = 10 - ($sum % 10); - - if ($checksum === 10) { - return '0'; - } - - return $checksum; - } -} diff --git a/lib/laminas/laminas-validator/src/LessThan.php b/lib/laminas/laminas-validator/src/LessThan.php deleted file mode 100644 index 1a646c239..000000000 --- a/lib/laminas/laminas-validator/src/LessThan.php +++ /dev/null @@ -1,158 +0,0 @@ - "The input is not less than '%max%'", - self::NOT_LESS_INCLUSIVE => "The input is not less or equal than '%max%'", - ]; - - /** - * Additional variables available for validation failure messages - * - * @var array - */ - protected $messageVariables = [ - 'max' => 'max', - ]; - - /** - * Maximum value - * - * @var mixed - */ - protected $max; - - /** - * Whether to do inclusive comparisons, allowing equivalence to max - * - * If false, then strict comparisons are done, and the value may equal - * the max option - * - * @var bool - */ - protected $inclusive; - - /** - * Sets validator options - * - * @param array|Traversable $options - * @throws Exception\InvalidArgumentException - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - if (! is_array($options)) { - $options = func_get_args(); - $temp['max'] = array_shift($options); - - if (! empty($options)) { - $temp['inclusive'] = array_shift($options); - } - - $options = $temp; - } - - if (! array_key_exists('max', $options)) { - throw new Exception\InvalidArgumentException("Missing option 'max'"); - } - - if (! array_key_exists('inclusive', $options)) { - $options['inclusive'] = false; - } - - $this->setMax($options['max']) - ->setInclusive($options['inclusive']); - - parent::__construct($options); - } - - /** - * Returns the max option - * - * @return mixed - */ - public function getMax() - { - return $this->max; - } - - /** - * Sets the max option - * - * @return $this Provides a fluent interface - */ - public function setMax(mixed $max) - { - $this->max = $max; - return $this; - } - - /** - * Returns the inclusive option - * - * @return bool - */ - public function getInclusive() - { - return $this->inclusive; - } - - /** - * Sets the inclusive option - * - * @param bool $inclusive - * @return $this Provides a fluent interface - */ - public function setInclusive($inclusive) - { - $this->inclusive = $inclusive; - return $this; - } - - /** - * Returns true if and only if $value is less than max option, inclusively - * when the inclusive option is true - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - $this->setValue($value); - - if ($this->inclusive) { - if ($value > $this->max) { - $this->error(self::NOT_LESS_INCLUSIVE); - return false; - } - } else { - if ($value >= $this->max) { - $this->error(self::NOT_LESS); - return false; - } - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Module.php b/lib/laminas/laminas-validator/src/Module.php deleted file mode 100644 index d95016ee6..000000000 --- a/lib/laminas/laminas-validator/src/Module.php +++ /dev/null @@ -1,43 +0,0 @@ - $provider->getDependencyConfig(), - ]; - } - - /** - * Register a specification for the ValidatorManager with the ServiceListener. - * - * @param ModuleManager $moduleManager - * @return void - */ - public function init($moduleManager) - { - $event = $moduleManager->getEvent(); - $container = $event->getParam('ServiceManager'); - $serviceListener = $container->get('ServiceListener'); - - $serviceListener->addServiceManager( - 'ValidatorManager', - 'validators', - ValidatorProviderInterface::class, - 'getValidatorConfig' - ); - } -} diff --git a/lib/laminas/laminas-validator/src/NotEmpty.php b/lib/laminas/laminas-validator/src/NotEmpty.php deleted file mode 100644 index b342974f7..000000000 --- a/lib/laminas/laminas-validator/src/NotEmpty.php +++ /dev/null @@ -1,306 +0,0 @@ - */ - protected $constants = [ - self::BOOLEAN => 'boolean', - self::INTEGER => 'integer', - self::FLOAT => 'float', - self::STRING => 'string', - self::ZERO => 'zero', - self::EMPTY_ARRAY => 'array', - self::NULL => 'null', - self::PHP => 'php', - self::SPACE => 'space', - self::OBJECT => 'object', - self::OBJECT_STRING => 'objectstring', - self::OBJECT_COUNT => 'objectcount', - self::ALL => 'all', - ]; - - /** - * Default value for types; value = 0b000111101001 - * - * @var array - */ - protected $defaultType = [ - self::OBJECT, - self::SPACE, - self::NULL, - self::EMPTY_ARRAY, - self::STRING, - self::BOOLEAN, - ]; - - /** @var array */ - protected $messageTemplates = [ - self::IS_EMPTY => "Value is required and can't be empty", - self::INVALID => 'Invalid type given. String, integer, float, boolean or array expected', - ]; - - /** - * Options for this validator - * - * @var array - */ - protected $options = []; - - /** - * Constructor - * - * @param array|Traversable|int $options OPTIONAL - */ - public function __construct($options = null) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } - - if (! is_array($options)) { - $options = func_get_args(); - $temp = []; - if (! empty($options)) { - $temp['type'] = array_shift($options); - } - - $options = $temp; - } - - if (! isset($options['type'])) { - if (($type = $this->calculateTypeValue($options)) !== 0) { - $options['type'] = $type; - } else { - $options['type'] = $this->defaultType; - } - } - - parent::__construct($options); - } - - /** - * Returns the set types - * - * @return int - */ - public function getType() - { - return $this->options['type']; - } - - /** - * @return false|int|string - */ - public function getDefaultType() - { - return $this->calculateTypeValue($this->defaultType); - } - - /** - * @param array|int|string $type - * @return false|int|string - */ - protected function calculateTypeValue($type) - { - if (is_array($type)) { - $detected = 0; - foreach ($type as $value) { - if (is_int($value)) { - $detected |= $value; - } elseif (in_array($value, $this->constants, true)) { - $detected |= (int) array_search($value, $this->constants, true); - } - } - - $type = $detected; - } elseif (is_string($type) && in_array($type, $this->constants, true)) { - $type = array_search($type, $this->constants, true); - } - - return $type; - } - - /** - * Set the types - * - * @param int|int[] $type - * @throws Exception\InvalidArgumentException - * @return $this - */ - public function setType($type = null) - { - $type = $this->calculateTypeValue($type); - - if (! is_int($type) || ($type < 0) || ($type > self::ALL)) { - throw new Exception\InvalidArgumentException('Unknown type'); - } - - $this->options['type'] = $type; - - return $this; - } - - /** - * Returns true if and only if $value is not an empty value. - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - if ( - $value !== null - && ! is_string($value) - && ! is_int($value) - && ! is_float($value) - && ! is_bool($value) - && ! is_array($value) - && ! is_object($value) - ) { - $this->error(self::INVALID); - return false; - } - - $type = $this->getType(); - $this->setValue($value); - $object = false; - - // OBJECT_COUNT (countable object) - if ($type & self::OBJECT_COUNT) { - $object = true; - - if (is_object($value) && $value instanceof Countable && (count($value) === 0)) { - $this->error(self::IS_EMPTY); - return false; - } - } - - // OBJECT_STRING (object's toString) - if ($type & self::OBJECT_STRING) { - $object = true; - - if ( - (is_object($value) && ! method_exists($value, '__toString')) - || (is_object($value) && method_exists($value, '__toString') && (string) $value === '') - ) { - $this->error(self::IS_EMPTY); - return false; - } - } - - // OBJECT (object) - // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf - if ($type & self::OBJECT) { - // fall through, objects are always not empty - } elseif ($object === false) { - // object not allowed but object given -> return false - if (is_object($value)) { - $this->error(self::IS_EMPTY); - return false; - } - } - - // SPACE (' ') - if ($type & self::SPACE) { - if (is_string($value) && (preg_match('/^\s+$/s', $value))) { - $this->error(self::IS_EMPTY); - return false; - } - } - - // NULL (null) - if ($type & self::NULL) { - if ($value === null) { - $this->error(self::IS_EMPTY); - return false; - } - } - - // EMPTY_ARRAY (array()) - if ($type & self::EMPTY_ARRAY) { - if ($value === []) { - $this->error(self::IS_EMPTY); - return false; - } - } - - // ZERO ('0') - if ($type & self::ZERO) { - if ($value === '0') { - $this->error(self::IS_EMPTY); - return false; - } - } - - // STRING ('') - if ($type & self::STRING) { - if ($value === '') { - $this->error(self::IS_EMPTY); - return false; - } - } - - // FLOAT (0.0) - if ($type & self::FLOAT) { - if ($value === 0.0) { - $this->error(self::IS_EMPTY); - return false; - } - } - - // INTEGER (0) - if ($type & self::INTEGER) { - if ($value === 0) { - $this->error(self::IS_EMPTY); - return false; - } - } - - // BOOLEAN (false) - if ($type & self::BOOLEAN) { - if ($value === false) { - $this->error(self::IS_EMPTY); - return false; - } - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Regex.php b/lib/laminas/laminas-validator/src/Regex.php deleted file mode 100644 index d022fe3e9..000000000 --- a/lib/laminas/laminas-validator/src/Regex.php +++ /dev/null @@ -1,137 +0,0 @@ - 'Invalid type given. String, integer or float expected', - self::NOT_MATCH => "The input does not match against pattern '%pattern%'", - self::ERROROUS => "There was an internal error while using the pattern '%pattern%'", - ]; - - /** @var array */ - protected $messageVariables = [ - 'pattern' => 'pattern', - ]; - - /** - * Regular expression pattern - * - * @var string - */ - protected $pattern; - - /** - * Sets validator options - * - * @param string|array|Traversable $pattern - * @throws Exception\InvalidArgumentException On missing 'pattern' parameter. - */ - public function __construct($pattern) - { - if (is_string($pattern)) { - $this->setPattern($pattern); - parent::__construct([]); - return; - } - - if ($pattern instanceof Traversable) { - $pattern = ArrayUtils::iteratorToArray($pattern); - } - - if (! is_array($pattern)) { - throw new Exception\InvalidArgumentException('Invalid options provided to constructor'); - } - - if (! array_key_exists('pattern', $pattern)) { - throw new Exception\InvalidArgumentException("Missing option 'pattern'"); - } - - $this->setPattern($pattern['pattern']); - unset($pattern['pattern']); - parent::__construct($pattern); - } - - /** - * Returns the pattern option - * - * @return string - */ - public function getPattern() - { - return $this->pattern; - } - - /** - * Sets the pattern option - * - * @param string $pattern - * @throws Exception\InvalidArgumentException If there is a fatal error in pattern matching. - * @return $this Provides a fluent interface - */ - public function setPattern($pattern) - { - ErrorHandler::start(); - $this->pattern = (string) $pattern; - $status = preg_match($this->pattern, 'Test'); - $error = ErrorHandler::stop(); - - if (false === $status) { - throw new Exception\InvalidArgumentException( - "Internal error parsing the pattern '{$this->pattern}'", - 0, - $error - ); - } - - return $this; - } - - /** - * Returns true if and only if $value matches against the pattern option - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value) && ! is_int($value) && ! is_float($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - - ErrorHandler::start(); - $status = preg_match($this->pattern, $value); - ErrorHandler::stop(); - if (false === $status) { - $this->error(self::ERROROUS); - return false; - } - - if (! $status) { - $this->error(self::NOT_MATCH); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Sitemap/Changefreq.php b/lib/laminas/laminas-validator/src/Sitemap/Changefreq.php deleted file mode 100644 index af1cac18e..000000000 --- a/lib/laminas/laminas-validator/src/Sitemap/Changefreq.php +++ /dev/null @@ -1,72 +0,0 @@ - value - * - * @link http://www.sitemaps.org/protocol.php Sitemaps XML format - */ -class Changefreq extends AbstractValidator -{ - /** - * Validation key for not valid - */ - public const NOT_VALID = 'sitemapChangefreqNotValid'; - public const INVALID = 'sitemapChangefreqInvalid'; - - /** - * Validation failure message template definitions - * - * @var array - */ - protected $messageTemplates = [ - self::NOT_VALID => 'The input is not a valid sitemap changefreq', - self::INVALID => 'Invalid type given. String expected', - ]; - - /** - * Valid change frequencies - * - * @var array - */ - protected $changeFreqs = [ - 'always', - 'hourly', - 'daily', - 'weekly', - 'monthly', - 'yearly', - 'never', - ]; - - /** - * Validates if a string is valid as a sitemap changefreq - * - * @link http://www.sitemaps.org/protocol.php#changefreqdef - * - * @param string $value value to validate - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - - if (! in_array($value, $this->changeFreqs, true)) { - $this->error(self::NOT_VALID); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Sitemap/Lastmod.php b/lib/laminas/laminas-validator/src/Sitemap/Lastmod.php deleted file mode 100644 index 2f6884e4c..000000000 --- a/lib/laminas/laminas-validator/src/Sitemap/Lastmod.php +++ /dev/null @@ -1,69 +0,0 @@ - value - * - * @link http://www.sitemaps.org/protocol.php Sitemaps XML format - */ -class Lastmod extends AbstractValidator -{ - // phpcs:disable Generic.Files.LineLength.TooLong - - /** - * Regular expression to use when validating - */ - public const LASTMOD_REGEX = '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])(T([0-1][0-9]|2[0-3])(:[0-5][0-9])(:[0-5][0-9])?(\\+|-)([0-1][0-9]|2[0-3]):[0-5][0-9])?$/'; - - // phpcs:enable - - /** - * Validation key for not valid - */ - public const NOT_VALID = 'sitemapLastmodNotValid'; - public const INVALID = 'sitemapLastmodInvalid'; - - /** - * Validation failure message template definitions - * - * @var array - */ - protected $messageTemplates = [ - self::NOT_VALID => 'The input is not a valid sitemap lastmod', - self::INVALID => 'Invalid type given. String expected', - ]; - - /** - * Validates if a string is valid as a sitemap lastmod - * - * @link http://www.sitemaps.org/protocol.php#lastmoddef - * - * @param string $value value to validate - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - ErrorHandler::start(); - $result = preg_match(self::LASTMOD_REGEX, $value); - ErrorHandler::stop(); - if ($result !== 1) { - $this->error(self::NOT_VALID); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Sitemap/Loc.php b/lib/laminas/laminas-validator/src/Sitemap/Loc.php deleted file mode 100644 index 447a92d4d..000000000 --- a/lib/laminas/laminas-validator/src/Sitemap/Loc.php +++ /dev/null @@ -1,58 +0,0 @@ - value - * - * @link http://www.sitemaps.org/protocol.php Sitemaps XML format - * @see Laminas\Uri\Uri - */ -class Loc extends AbstractValidator -{ - /** - * Validation key for not valid - */ - public const NOT_VALID = 'sitemapLocNotValid'; - public const INVALID = 'sitemapLocInvalid'; - - /** - * Validation failure message template definitions - * - * @var array - */ - protected $messageTemplates = [ - self::NOT_VALID => 'The input is not a valid sitemap location', - self::INVALID => 'Invalid type given. String expected', - ]; - - /** - * Validates if a string is valid as a sitemap location - * - * @link http://www.sitemaps.org/protocol.php#locdef - * - * @param string $value value to validate - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - $uri = Uri\UriFactory::factory($value); - if (! $uri->isValid()) { - $this->error(self::NOT_VALID); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Sitemap/Priority.php b/lib/laminas/laminas-validator/src/Sitemap/Priority.php deleted file mode 100644 index 7bf6c02b8..000000000 --- a/lib/laminas/laminas-validator/src/Sitemap/Priority.php +++ /dev/null @@ -1,56 +0,0 @@ - value - * - * @link http://www.sitemaps.org/protocol.php Sitemaps XML format - */ -class Priority extends AbstractValidator -{ - /** - * Validation key for not valid - */ - public const NOT_VALID = 'sitemapPriorityNotValid'; - public const INVALID = 'sitemapPriorityInvalid'; - - /** - * Validation failure message template definitions - * - * @var array - */ - protected $messageTemplates = [ - self::NOT_VALID => 'The input is not a valid sitemap priority', - self::INVALID => 'Invalid type given. Numeric string, integer or float expected', - ]; - - /** - * Validates if a string is valid as a sitemap priority - * - * @link http://www.sitemaps.org/protocol.php#prioritydef - * - * @param string $value value to validate - * @return bool - */ - public function isValid($value) - { - if (! is_numeric($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - $value = (float) $value; - if ($value < 0 || $value > 1) { - $this->error(self::NOT_VALID); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/StaticValidator.php b/lib/laminas/laminas-validator/src/StaticValidator.php deleted file mode 100644 index a99dded2e..000000000 --- a/lib/laminas/laminas-validator/src/StaticValidator.php +++ /dev/null @@ -1,70 +0,0 @@ -configure(['shared_by_default' => false]); - } else { - $plugins->setShareByDefault(false); - } - } - static::$plugins = $plugins; - } - - /** - * Get plugin manager for locating validators - * - * @return ValidatorPluginManager - */ - public static function getPluginManager() - { - if (! static::$plugins instanceof ValidatorPluginManager) { - $plugins = new ValidatorPluginManager(new ServiceManager()); - static::setPluginManager($plugins); - - return $plugins; - } - return static::$plugins; - } - - /** - * @param class-string $classBaseName - * @param array $options OPTIONAL associative array of options to pass as - * the sole argument to the validator constructor. - * @return bool - * @throws Exception\InvalidArgumentException For an invalid $options argument. - */ - public static function execute(mixed $value, $classBaseName, array $options = []) - { - if ($options && array_values($options) === $options) { - throw new Exception\InvalidArgumentException( - 'Invalid options provided via $options argument; must be an associative array' - ); - } - - $plugins = static::getPluginManager(); - - $validator = $plugins->get($classBaseName, $options); - return $validator->isValid($value); - } -} diff --git a/lib/laminas/laminas-validator/src/Step.php b/lib/laminas/laminas-validator/src/Step.php deleted file mode 100644 index 8ae925f28..000000000 --- a/lib/laminas/laminas-validator/src/Step.php +++ /dev/null @@ -1,174 +0,0 @@ - 'Invalid value given. Scalar expected', - self::NOT_STEP => 'The input is not a valid step', - ]; - - /** @var mixed */ - protected $baseValue = 0; - - /** @var mixed */ - protected $step = 1; - - /** - * Set default options for this instance - * - * @param array $options - */ - public function __construct($options = []) - { - if ($options instanceof Traversable) { - $options = iterator_to_array($options); - } elseif (! is_array($options)) { - $options = func_get_args(); - $temp['baseValue'] = array_shift($options); - if (! empty($options)) { - $temp['step'] = array_shift($options); - } - - $options = $temp; - } - - if (isset($options['baseValue'])) { - $this->setBaseValue($options['baseValue']); - } - if (isset($options['step'])) { - $this->setStep($options['step']); - } - - parent::__construct($options); - } - - /** - * Sets the base value from which the step should be computed - * - * @return $this - */ - public function setBaseValue(mixed $baseValue) - { - $this->baseValue = $baseValue; - return $this; - } - - /** - * Returns the base value from which the step should be computed - * - * @return string - */ - public function getBaseValue() - { - return $this->baseValue; - } - - /** - * Sets the step value - * - * @return $this - */ - public function setStep(mixed $step) - { - $this->step = (float) $step; - return $this; - } - - /** - * Returns the step value - * - * @return string - */ - public function getStep() - { - return $this->step; - } - - /** - * Returns true if $value is a scalar and a valid step value - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - if (! is_numeric($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - - $substract = $this->sub($value, $this->baseValue); - - $fmod = $this->fmod($substract, $this->step); - - if ($fmod !== 0.0 && $fmod !== $this->step) { - $this->error(self::NOT_STEP); - return false; - } - - return true; - } - - /** - * replaces the internal fmod function which give wrong results on many cases - * - * @param int|float $x - * @param int|float $y - * @return float - */ - protected function fmod($x, $y) - { - if ($y === 0.0 || $y === 0) { - return 1.0; - } - - //find the maximum precision from both input params to give accurate results - $precision = $this->getPrecision($x) + $this->getPrecision($y); - - return round($x - $y * floor($x / $y), $precision); - } - - /** - * replaces the internal substraction operation which give wrong results on some cases - * - * @param float $x - * @param float $y - * @return float - */ - private function sub($x, $y) - { - $precision = $this->getPrecision($x) + $this->getPrecision($y); - return round($x - $y, $precision); - } - - /** - * @param float $float - * @return int - */ - private function getPrecision($float) - { - $segment = substr($float, strpos($float, '.') + 1); - return $segment ? strlen($segment) : 0; - } -} diff --git a/lib/laminas/laminas-validator/src/StringLength.php b/lib/laminas/laminas-validator/src/StringLength.php deleted file mode 100644 index 64edff34b..000000000 --- a/lib/laminas/laminas-validator/src/StringLength.php +++ /dev/null @@ -1,233 +0,0 @@ - */ - protected $messageTemplates = [ - self::INVALID => 'Invalid type given. String expected', - self::TOO_SHORT => 'The input is less than %min% characters long', - self::TOO_LONG => 'The input is more than %max% characters long', - ]; - - /** @var array> */ - protected $messageVariables = [ - 'min' => ['options' => 'min'], - 'max' => ['options' => 'max'], - 'length' => ['options' => 'length'], - ]; - - /** @var array */ - protected $options = [ - 'min' => 0, // Minimum length - 'max' => null, // Maximum length, null if there is no length limitation - 'encoding' => 'UTF-8', // Encoding to use - 'length' => 0, // Actual length - ]; - - /** @var null|StringWrapperInterface */ - protected $stringWrapper; - - /** - * Sets validator options - * - * @param int|array|Traversable $options - */ - public function __construct($options = []) - { - if (! is_array($options)) { - $options = func_get_args(); - $temp['min'] = array_shift($options); - if (! empty($options)) { - $temp['max'] = array_shift($options); - } - - if (! empty($options)) { - $temp['encoding'] = array_shift($options); - } - - $options = $temp; - } - - parent::__construct($options); - } - - /** - * Returns the min option - * - * @return int - */ - public function getMin() - { - return $this->options['min']; - } - - /** - * Sets the min option - * - * @param int $min - * @throws Exception\InvalidArgumentException - * @return $this Provides a fluent interface - */ - public function setMin($min) - { - if (null !== $this->getMax() && $min > $this->getMax()) { - throw new Exception\InvalidArgumentException( - "The minimum must be less than or equal to the maximum length, but {$min} > {$this->getMax()}" - ); - } - - $this->options['min'] = max(0, (int) $min); - return $this; - } - - /** - * Returns the max option - * - * @return int|null - */ - public function getMax() - { - return $this->options['max']; - } - - /** - * Sets the max option - * - * @param int|null $max - * @throws Exception\InvalidArgumentException - * @return $this Provides a fluent interface - */ - public function setMax($max) - { - if (null === $max) { - $this->options['max'] = null; - } elseif ($max < $this->getMin()) { - throw new Exception\InvalidArgumentException( - "The maximum must be greater than or equal to the minimum length, but {$max} < {$this->getMin()}" - ); - } else { - $this->options['max'] = (int) $max; - } - - return $this; - } - - /** - * Get the string wrapper to detect the string length - * - * @return StringWrapper - */ - public function getStringWrapper() - { - if (! $this->stringWrapper) { - $this->stringWrapper = StringUtils::getWrapper($this->getEncoding()); - } - return $this->stringWrapper; - } - - /** - * Set the string wrapper to detect the string length - * - * @return void - */ - public function setStringWrapper(StringWrapper $stringWrapper) - { - $stringWrapper->setEncoding($this->getEncoding()); - $this->stringWrapper = $stringWrapper; - } - - /** - * Returns the actual encoding - * - * @return string - */ - public function getEncoding() - { - return $this->options['encoding']; - } - - /** - * Sets a new encoding to use - * - * @param string $encoding - * @return $this - * @throws Exception\InvalidArgumentException - */ - public function setEncoding($encoding) - { - $this->stringWrapper = StringUtils::getWrapper($encoding); - $this->options['encoding'] = $encoding; - return $this; - } - - /** - * Returns the length option - * - * @return int - */ - private function getLength() - { - return $this->options['length']; - } - - /** - * Sets the length option - * - * @param int $length - * @return $this Provides a fluent interface - */ - private function setLength($length) - { - $this->options['length'] = (int) $length; - return $this; - } - - /** - * Returns true if and only if the string length of $value is at least the min option and - * no greater than the max option (when the max option is not null). - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $this->setValue($value); - - $this->setLength($this->getStringWrapper()->strlen($value)); - if ($this->getLength() < $this->getMin()) { - $this->error(self::TOO_SHORT); - } - - if (null !== $this->getMax() && $this->getMax() < $this->getLength()) { - $this->error(self::TOO_LONG); - } - - if ($this->getMessages()) { - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/Timezone.php b/lib/laminas/laminas-validator/src/Timezone.php deleted file mode 100644 index 5842adcc1..000000000 --- a/lib/laminas/laminas-validator/src/Timezone.php +++ /dev/null @@ -1,170 +0,0 @@ - 'location', - self::ABBREVIATION => 'abbreviation', - ]; - - /** - * Default value for types; value = 3 - * - * @var array - */ - protected $defaultType = [ - self::LOCATION, - self::ABBREVIATION, - ]; - - /** @var array */ - protected $messageTemplates = [ - self::INVALID => 'Invalid timezone given.', - self::INVALID_TIMEZONE_LOCATION => 'Invalid timezone location given.', - self::INVALID_TIMEZONE_ABBREVIATION => 'Invalid timezone abbreviation given.', - ]; - - /** - * Options for this validator - * - * @var array - */ - protected $options = []; - - /** - * Constructor - * - * @param array|int $options OPTIONAL - */ - public function __construct($options = []) - { - $opts['type'] = $this->defaultType; - - if (is_array($options)) { - if (array_key_exists('type', $options)) { - $opts['type'] = $options['type']; - } - } elseif (! empty($options)) { - $opts['type'] = $options; - } - - // setType called by parent constructor then setOptions method - parent::__construct($opts); - } - - /** - * Set the types - * - * @param int|array $type - * @return void - * @throws Exception\InvalidArgumentException - */ - public function setType($type = null) - { - $type = $this->calculateTypeValue($type); - - if (! is_int($type) || ($type < 1) || ($type > self::ALL)) { - throw new Exception\InvalidArgumentException(sprintf( - 'Unknown type "%s" provided', - is_string($type) || is_int($type) - ? $type : gettype($type) - )); - } - - $this->options['type'] = $type; - } - - /** - * Returns true if timezone location or timezone abbreviations is correct. - * - * @param mixed $value - * @return bool - */ - public function isValid($value) - { - if ($value !== null && ! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $type = $this->options['type']; - $this->setValue($value); - - switch (true) { - // Check in locations and abbreviations - case ($type & self::LOCATION) && ($type & self::ABBREVIATION): - $abbrs = DateTimeZone::listAbbreviations(); - $locations = DateTimeZone::listIdentifiers(); - - if (! array_key_exists($value, $abbrs) && ! in_array($value, $locations)) { - $this->error(self::INVALID); - return false; - } - break; - - // Check only in locations - case $type & self::LOCATION: - $locations = DateTimeZone::listIdentifiers(); - - if (! in_array($value, $locations)) { - $this->error(self::INVALID_TIMEZONE_LOCATION); - return false; - } - break; - - // Check only in abbreviations - case $type & self::ABBREVIATION: - $abbrs = DateTimeZone::listAbbreviations(); - - if (! array_key_exists($value, $abbrs)) { - $this->error(self::INVALID_TIMEZONE_ABBREVIATION); - return false; - } - break; - } - - return true; - } - - /** - * @param array|int|string $type - * @return float|int - */ - protected function calculateTypeValue($type) - { - $types = (array) $type; - $detected = 0; - - foreach ($types as $value) { - if (is_int($value)) { - $detected |= $value; - } elseif (false !== array_search($value, $this->constants)) { - $detected |= array_search($value, $this->constants); - } - } - - return $detected; - } -} diff --git a/lib/laminas/laminas-validator/src/Translator/TranslatorAwareInterface.php b/lib/laminas/laminas-validator/src/Translator/TranslatorAwareInterface.php deleted file mode 100644 index 9702abc8c..000000000 --- a/lib/laminas/laminas-validator/src/Translator/TranslatorAwareInterface.php +++ /dev/null @@ -1,62 +0,0 @@ - */ - protected $messageTemplates = [ - self::PASSWORD_BREACHED => 'The provided password was found in previous breaches, please create another password', - self::NOT_A_STRING => 'The provided password is not a string, please provide a correct password', - ]; - - // phpcs:enable - public function __construct(private ClientInterface $httpClient, private RequestFactoryInterface $makeHttpRequest) - { - parent::__construct(); - } - - /** {@inheritDoc} */ - public function isValid($value): bool - { - if (! is_string($value)) { - $this->error(self::NOT_A_STRING); - return false; - } - - if ($this->isPwnedPassword($value)) { - $this->error(self::PASSWORD_BREACHED); - return false; - } - - return true; - } - - private function isPwnedPassword(string $password): bool - { - $sha1Hash = $this->hashPassword($password); - $rangeHash = $this->getRangeHash($sha1Hash); - $hashList = $this->retrieveHashList($rangeHash); - - return $this->hashInResponse($sha1Hash, $hashList); - } - - /** - * We use a SHA1 hashed password for checking it against - * the breached data set of HIBP. - */ - private function hashPassword(string $password): string - { - $hashedPassword = sha1($password); - - return strtoupper($hashedPassword); - } - - /** - * Creates a hash range that will be send to HIBP API - * applying K-Anonymity - * - * @see https://www.troyhunt.com/enhancing-pwned-passwords-privacy-by-exclusively-supporting-anonymity/ - */ - private function getRangeHash(string $passwordHash): string - { - return substr($passwordHash, self::HIBP_K_ANONYMITY_HASH_RANGE_BASE, self::HIBP_K_ANONYMITY_HASH_RANGE_LENGTH); - } - - /** - * Making a connection to the HIBP API to retrieve a - * list of hashes that all have the same range as we - * provided. - * - * @throws ClientExceptionInterface - */ - private function retrieveHashList(string $passwordRange): string - { - $request = $this->makeHttpRequest->createRequest( - 'GET', - self::HIBP_API_URI . '/range/' . $passwordRange - ); - - $response = $this->httpClient->sendRequest($request); - return (string) $response->getBody(); - } - - /** - * Checks if the password is in the response from HIBP - */ - private function hashInResponse(string $sha1Hash, string $resultStream): bool - { - $data = explode("\r\n", $resultStream); - $hashes = array_filter($data, static function ($value) use ($sha1Hash): bool { - [$hash] = explode(':', $value); - - return strcmp($hash, substr($sha1Hash, self::HIBP_K_ANONYMITY_HASH_RANGE_LENGTH)) === 0; - }); - - return $hashes !== []; - } -} diff --git a/lib/laminas/laminas-validator/src/Uri.php b/lib/laminas/laminas-validator/src/Uri.php deleted file mode 100644 index cb719654f..000000000 --- a/lib/laminas/laminas-validator/src/Uri.php +++ /dev/null @@ -1,185 +0,0 @@ - */ - protected $messageTemplates = [ - self::INVALID => 'Invalid type given. String expected', - self::NOT_URI => 'The input does not appear to be a valid Uri', - ]; - - /** @var UriHandler */ - protected $uriHandler; - - /** @var bool */ - protected $allowRelative = true; - - /** @var bool */ - protected $allowAbsolute = true; - - /** - * Sets default option values for this instance - * - * @param array|Traversable $options - */ - public function __construct($options = []) - { - if ($options instanceof Traversable) { - $options = iterator_to_array($options); - } elseif (! is_array($options)) { - $options = func_get_args(); - $temp['uriHandler'] = array_shift($options); - if (! empty($options)) { - $temp['allowRelative'] = array_shift($options); - } - if (! empty($options)) { - $temp['allowAbsolute'] = array_shift($options); - } - - $options = $temp; - } - - if (isset($options['uriHandler'])) { - $this->setUriHandler($options['uriHandler']); - } - if (isset($options['allowRelative'])) { - $this->setAllowRelative($options['allowRelative']); - } - if (isset($options['allowAbsolute'])) { - $this->setAllowAbsolute($options['allowAbsolute']); - } - - parent::__construct($options); - } - - /** - * @throws InvalidArgumentException - * @return UriHandler - */ - public function getUriHandler() - { - if (null === $this->uriHandler) { - // Lazy load the base Uri handler - $this->uriHandler = new UriHandler(); - } elseif (is_string($this->uriHandler) && class_exists($this->uriHandler)) { - // Instantiate string Uri handler that references a class - $this->uriHandler = new $this->uriHandler(); - } - return $this->uriHandler; - } - - /** - * @param UriHandler|string $uriHandler - * @throws InvalidArgumentException - * @return $this - */ - public function setUriHandler($uriHandler) - { - if (! is_a($uriHandler, UriHandler::class, true)) { - throw new InvalidArgumentException(sprintf( - 'Expecting a subclass name or instance of %s as $uriHandler', - UriHandler::class - )); - } - - $this->uriHandler = $uriHandler; - return $this; - } - - /** - * Returns the allowAbsolute option - * - * @return bool - */ - public function getAllowAbsolute() - { - return $this->allowAbsolute; - } - - /** - * Sets the allowAbsolute option - * - * @param bool $allowAbsolute - * @return $this - */ - public function setAllowAbsolute($allowAbsolute) - { - $this->allowAbsolute = (bool) $allowAbsolute; - return $this; - } - - /** - * Returns the allowRelative option - * - * @return bool - */ - public function getAllowRelative() - { - return $this->allowRelative; - } - - /** - * Sets the allowRelative option - * - * @param bool $allowRelative - * @return $this - */ - public function setAllowRelative($allowRelative) - { - $this->allowRelative = (bool) $allowRelative; - return $this; - } - - /** - * Returns true if and only if $value validates as a Uri - * - * @param string $value - * @return bool - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::INVALID); - return false; - } - - $uriHandler = $this->getUriHandler(); - try { - $uriHandler->parse($value); - if ($uriHandler->isValid()) { - // It will either be a valid absolute or relative URI - if ( - ($this->allowRelative && $this->allowAbsolute) - || ($this->allowAbsolute && $uriHandler->isAbsolute()) - || ($this->allowRelative && $uriHandler->isValidRelative()) - ) { - return true; - } - } - } catch (UriException) { - // Error parsing URI, it must be invalid - } - - $this->error(self::NOT_URI); - return false; - } -} diff --git a/lib/laminas/laminas-validator/src/Uuid.php b/lib/laminas/laminas-validator/src/Uuid.php deleted file mode 100644 index 77ecdd8b3..000000000 --- a/lib/laminas/laminas-validator/src/Uuid.php +++ /dev/null @@ -1,58 +0,0 @@ - 'Invalid type given; string expected', - self::INVALID => 'Invalid UUID format', - ]; - - /** - * Returns true if and only if $value meets the validation requirements. - * - * If $value fails validation, then this method returns false, and - * getMessages() will return an array of messages that explain why the - * validation failed. - * - * @param mixed $value - * @return bool - * @throws Exception\RuntimeException If validation of $value is impossible. - */ - public function isValid($value) - { - if (! is_string($value)) { - $this->error(self::NOT_STRING); - return false; - } - - $this->setValue($value); - - if ( - empty($value) - || $value !== '00000000-0000-0000-0000-000000000000' - && ! preg_match(self::REGEX_UUID, $value) - ) { - $this->error(self::INVALID); - return false; - } - - return true; - } -} diff --git a/lib/laminas/laminas-validator/src/ValidatorChain.php b/lib/laminas/laminas-validator/src/ValidatorChain.php deleted file mode 100644 index d63141f5b..000000000 --- a/lib/laminas/laminas-validator/src/ValidatorChain.php +++ /dev/null @@ -1,341 +0,0 @@ - - * @final - */ -class ValidatorChain implements Countable, IteratorAggregate, ValidatorInterface -{ - /** - * Default priority at which validators are added - */ - public const DEFAULT_PRIORITY = 1; - - /** @var ValidatorPluginManager|null */ - protected $plugins; - - /** - * Validator chain - * - * @var PriorityQueue - */ - protected $validators; - - /** - * Array of validation failure messages - * - * @var array - */ - protected $messages = []; - - /** - * Initialize validator chain - */ - public function __construct() - { - /** @psalm-suppress InvalidPropertyAssignmentValue */ - $this->validators = new PriorityQueue(); - } - - /** - * Return the count of attached validators - * - * @return int - */ - #[ReturnTypeWillChange] - public function count() - { - return count($this->validators); - } - - /** - * Get plugin manager instance - * - * @return ValidatorPluginManager - */ - public function getPluginManager() - { - if (! $this->plugins) { - $this->setPluginManager(new ValidatorPluginManager(new ServiceManager())); - } - return $this->plugins; - } - - /** - * Set plugin manager instance - * - * @param ValidatorPluginManager $plugins Plugin manager - * @psalm-assert ValidatorPluginManager $this->plugins - * @return $this - */ - public function setPluginManager(ValidatorPluginManager $plugins) - { - $this->plugins = $plugins; - return $this; - } - - /** - * Retrieve a validator by name - * - * @param string|class-string $name Name of validator to return - * @param null|array $options Options to pass to validator constructor - * (if not already instantiated) - * @return ValidatorInterface - * @template T of ValidatorInterface - * @psalm-param string|class-string $name - * @psalm-return ValidatorInterface - */ - public function plugin($name, ?array $options = null) - { - $plugins = $this->getPluginManager(); - return $plugins->get($name, $options); - } - - /** - * Attach a validator to the end of the chain - * If $breakChainOnFailure is true, then if the validator fails, the next validator in the chain, - * if one exists, will not be executed. - * - * @param bool $breakChainOnFailure - * @param int $priority Priority at which to enqueue validator; defaults to - * 1 (higher executes earlier) - * @return $this - * @throws Exception\InvalidArgumentException - */ - public function attach( - ValidatorInterface $validator, - $breakChainOnFailure = false, - $priority = self::DEFAULT_PRIORITY - ) { - /** @psalm-suppress RedundantCastGivenDocblockType */ - $this->validators->insert( - [ - 'instance' => $validator, - 'breakChainOnFailure' => (bool) $breakChainOnFailure, - ], - $priority - ); - - return $this; - } - - /** - * Proxy to attach() to keep BC - * - * @deprecated Please use attach() - * - * @param bool $breakChainOnFailure - * @param int $priority - * @return ValidatorChain Provides a fluent interface - */ - public function addValidator( - ValidatorInterface $validator, - $breakChainOnFailure = false, - $priority = self::DEFAULT_PRIORITY - ) { - return $this->attach($validator, $breakChainOnFailure, $priority); - } - - /** - * Adds a validator to the beginning of the chain - * - * If $breakChainOnFailure is true, then if the validator fails, the next validator in the chain, - * if one exists, will not be executed. - * - * @param bool $breakChainOnFailure - * @return $this Provides a fluent interface - */ - public function prependValidator(ValidatorInterface $validator, $breakChainOnFailure = false) - { - $priority = self::DEFAULT_PRIORITY; - - if (! $this->validators->isEmpty()) { - $extractedNodes = $this->validators->toArray(PriorityQueue::EXTR_PRIORITY); - rsort($extractedNodes, SORT_NUMERIC); - $priority = $extractedNodes[0] + 1; - } - - /** @psalm-suppress RedundantCastGivenDocblockType */ - $this->validators->insert( - [ - 'instance' => $validator, - 'breakChainOnFailure' => (bool) $breakChainOnFailure, - ], - $priority - ); - return $this; - } - - /** - * Use the plugin manager to add a validator by name - * - * @param string|class-string $name - * @param array $options - * @param bool $breakChainOnFailure - * @param int $priority - * @return $this - */ - public function attachByName($name, $options = [], $breakChainOnFailure = false, $priority = self::DEFAULT_PRIORITY) - { - if (isset($options['break_chain_on_failure'])) { - $breakChainOnFailure = (bool) $options['break_chain_on_failure']; - } - - if (isset($options['breakchainonfailure'])) { - $breakChainOnFailure = (bool) $options['breakchainonfailure']; - } - - $this->attach($this->plugin($name, $options), $breakChainOnFailure, $priority); - - return $this; - } - - /** - * Proxy to attachByName() to keep BC - * - * @deprecated Please use attachByName() - * - * @param string $name - * @param array $options - * @param bool $breakChainOnFailure - * @return ValidatorChain - */ - public function addByName($name, $options = [], $breakChainOnFailure = false) - { - return $this->attachByName($name, $options, $breakChainOnFailure); - } - - /** - * Use the plugin manager to prepend a validator by name - * - * @param string|class-string $name - * @param array $options - * @param bool $breakChainOnFailure - * @return $this - */ - public function prependByName($name, $options = [], $breakChainOnFailure = false) - { - $validator = $this->plugin($name, $options); - $this->prependValidator($validator, $breakChainOnFailure); - return $this; - } - - /** - * Returns true if and only if $value passes all validations in the chain - * - * Validators are run in the order in which they were added to the chain (FIFO). - * - * @param mixed $value - * @param mixed $context Extra "context" to provide the validator - * @return bool - */ - public function isValid($value, $context = null) - { - $this->messages = []; - $result = true; - foreach ($this as $element) { - $validator = $element['instance']; - assert($validator instanceof ValidatorInterface); - if ($validator->isValid($value, $context)) { - continue; - } - $result = false; - $messages = $validator->getMessages(); - $this->messages = array_replace($this->messages, $messages); - if ($element['breakChainOnFailure']) { - break; - } - } - return $result; - } - - /** - * Merge the validator chain with the one given in parameter - * - * @return $this - */ - public function merge(ValidatorChain $validatorChain) - { - foreach ($validatorChain->validators->toArray(PriorityQueue::EXTR_BOTH) as $item) { - $this->attach($item['data']['instance'], $item['data']['breakChainOnFailure'], $item['priority']); - } - - return $this; - } - - /** - * Returns array of validation failure messages - * - * @return array - */ - public function getMessages() - { - return $this->messages; - } - - /** - * Get all the validators - * - * @return list - */ - public function getValidators() - { - return $this->validators->toArray(PriorityQueue::EXTR_DATA); - } - - /** - * Invoke chain as command - * - * @return bool - */ - public function __invoke(mixed $value) - { - return $this->isValid($value); - } - - /** - * Deep clone handling - */ - public function __clone() - { - $this->validators = clone $this->validators; - } - - /** - * Prepare validator chain for serialization - * - * Plugin manager (property 'plugins') cannot - * be serialized. On wakeup the property remains unset - * and next invocation to getPluginManager() sets - * the default plugin manager instance (ValidatorPluginManager). - * - * @return array - */ - public function __sleep() - { - return ['validators', 'messages']; - } - - /** @return Traversable */ - public function getIterator(): Traversable - { - return clone $this->validators; - } -} diff --git a/lib/laminas/laminas-validator/src/ValidatorInterface.php b/lib/laminas/laminas-validator/src/ValidatorInterface.php deleted file mode 100644 index af83fbd0a..000000000 --- a/lib/laminas/laminas-validator/src/ValidatorInterface.php +++ /dev/null @@ -1,39 +0,0 @@ -, - * priority?: int, - * break_chain_on_failure?: bool, - * options?: array, - * } - */ -interface ValidatorInterface -{ - /** - * Returns true if and only if $value meets the validation requirements - * - * If $value fails validation, then this method returns false, and - * getMessages() will return an array of messages that explain why the - * validation failed. - * - * @param mixed $value - * @return bool - * @throws Exception\RuntimeException If validation of $value is impossible. - */ - public function isValid($value); - - /** - * Returns an array of messages that explain why the most recent isValid() - * call returned false. The array keys are validation failure message identifiers, - * and the array values are the corresponding human-readable message strings. - * - * If isValid() was never called or if the most recent isValid() call - * returned true, then this method returns an empty array. - * - * @return array - */ - public function getMessages(); -} diff --git a/lib/laminas/laminas-validator/src/ValidatorPluginManager.php b/lib/laminas/laminas-validator/src/ValidatorPluginManager.php deleted file mode 100644 index 0cae3baef..000000000 --- a/lib/laminas/laminas-validator/src/ValidatorPluginManager.php +++ /dev/null @@ -1,657 +0,0 @@ - - */ -class ValidatorPluginManager extends AbstractPluginManager -{ - /** - * Default set of aliases - * - * @var array - * @psalm-suppress UndefinedClass - */ - protected $aliases = [ - 'alnum' => I18nValidator\Alnum::class, - 'Alnum' => I18nValidator\Alnum::class, - 'alpha' => I18nValidator\Alpha::class, - 'Alpha' => I18nValidator\Alpha::class, - 'barcode' => Barcode::class, - 'Barcode' => Barcode::class, - 'between' => Between::class, - 'Between' => Between::class, - 'BIC' => BusinessIdentifierCode::class, - 'bic' => BusinessIdentifierCode::class, - 'bitwise' => Bitwise::class, - 'Bitwise' => Bitwise::class, - 'BusinessIdentifierCode' => BusinessIdentifierCode::class, - 'businessidentifiercode' => BusinessIdentifierCode::class, - 'callback' => Callback::class, - 'Callback' => Callback::class, - 'creditcard' => CreditCard::class, - 'creditCard' => CreditCard::class, - 'CreditCard' => CreditCard::class, - 'csrf' => Csrf::class, - 'Csrf' => Csrf::class, - 'date' => Date::class, - 'Date' => Date::class, - 'datestep' => DateStep::class, - 'dateStep' => DateStep::class, - 'DateStep' => DateStep::class, - 'datetime' => I18nValidator\DateTime::class, - 'dateTime' => I18nValidator\DateTime::class, - 'DateTime' => I18nValidator\DateTime::class, - 'dbnorecordexists' => Db\NoRecordExists::class, - 'dbNoRecordExists' => Db\NoRecordExists::class, - 'DbNoRecordExists' => Db\NoRecordExists::class, - 'dbrecordexists' => Db\RecordExists::class, - 'dbRecordExists' => Db\RecordExists::class, - 'DbRecordExists' => Db\RecordExists::class, - 'digits' => Digits::class, - 'Digits' => Digits::class, - 'emailaddress' => EmailAddress::class, - 'emailAddress' => EmailAddress::class, - 'EmailAddress' => EmailAddress::class, - 'explode' => Explode::class, - 'Explode' => Explode::class, - 'filecount' => File\Count::class, - 'fileCount' => File\Count::class, - 'FileCount' => File\Count::class, - 'filecrc32' => File\Crc32::class, - 'fileCrc32' => File\Crc32::class, - 'FileCrc32' => File\Crc32::class, - 'fileexcludeextension' => File\ExcludeExtension::class, - 'fileExcludeExtension' => File\ExcludeExtension::class, - 'FileExcludeExtension' => File\ExcludeExtension::class, - 'fileexcludemimetype' => File\ExcludeMimeType::class, - 'fileExcludeMimeType' => File\ExcludeMimeType::class, - 'FileExcludeMimeType' => File\ExcludeMimeType::class, - 'fileexists' => File\Exists::class, - 'fileExists' => File\Exists::class, - 'FileExists' => File\Exists::class, - 'fileextension' => File\Extension::class, - 'fileExtension' => File\Extension::class, - 'FileExtension' => File\Extension::class, - 'filefilessize' => File\FilesSize::class, - 'fileFilesSize' => File\FilesSize::class, - 'FileFilesSize' => File\FilesSize::class, - 'filehash' => File\Hash::class, - 'fileHash' => File\Hash::class, - 'FileHash' => File\Hash::class, - 'fileimagesize' => File\ImageSize::class, - 'fileImageSize' => File\ImageSize::class, - 'FileImageSize' => File\ImageSize::class, - 'fileiscompressed' => File\IsCompressed::class, - 'fileIsCompressed' => File\IsCompressed::class, - 'FileIsCompressed' => File\IsCompressed::class, - 'fileisimage' => File\IsImage::class, - 'fileIsImage' => File\IsImage::class, - 'FileIsImage' => File\IsImage::class, - 'filemd5' => File\Md5::class, - 'fileMd5' => File\Md5::class, - 'FileMd5' => File\Md5::class, - 'filemimetype' => File\MimeType::class, - 'fileMimeType' => File\MimeType::class, - 'FileMimeType' => File\MimeType::class, - 'filenotexists' => File\NotExists::class, - 'fileNotExists' => File\NotExists::class, - 'FileNotExists' => File\NotExists::class, - 'filesha1' => File\Sha1::class, - 'fileSha1' => File\Sha1::class, - 'FileSha1' => File\Sha1::class, - 'filesize' => File\Size::class, - 'fileSize' => File\Size::class, - 'FileSize' => File\Size::class, - 'fileupload' => File\Upload::class, - 'fileUpload' => File\Upload::class, - 'FileUpload' => File\Upload::class, - 'fileuploadfile' => File\UploadFile::class, - 'fileUploadFile' => File\UploadFile::class, - 'FileUploadFile' => File\UploadFile::class, - 'filewordcount' => File\WordCount::class, - 'fileWordCount' => File\WordCount::class, - 'FileWordCount' => File\WordCount::class, - 'float' => I18nValidator\IsFloat::class, - 'Float' => I18nValidator\IsFloat::class, - 'gpspoint' => GpsPoint::class, - 'gpsPoint' => GpsPoint::class, - 'GpsPoint' => GpsPoint::class, - 'greaterthan' => GreaterThan::class, - 'greaterThan' => GreaterThan::class, - 'GreaterThan' => GreaterThan::class, - 'hex' => Hex::class, - 'Hex' => Hex::class, - 'hostname' => Hostname::class, - 'Hostname' => Hostname::class, - 'iban' => Iban::class, - 'Iban' => Iban::class, - 'identical' => Identical::class, - 'Identical' => Identical::class, - 'inarray' => InArray::class, - 'inArray' => InArray::class, - 'InArray' => InArray::class, - 'int' => I18nValidator\IsInt::class, - 'Int' => I18nValidator\IsInt::class, - 'ip' => Ip::class, - 'Ip' => Ip::class, - 'isbn' => Isbn::class, - 'Isbn' => Isbn::class, - 'isCountable' => IsCountable::class, - 'IsCountable' => IsCountable::class, - 'iscountable' => IsCountable::class, - 'isfloat' => I18nValidator\IsFloat::class, - 'isFloat' => I18nValidator\IsFloat::class, - 'IsFloat' => I18nValidator\IsFloat::class, - 'isinstanceof' => IsInstanceOf::class, - 'isInstanceOf' => IsInstanceOf::class, - 'IsInstanceOf' => IsInstanceOf::class, - 'isint' => I18nValidator\IsInt::class, - 'isInt' => I18nValidator\IsInt::class, - 'IsInt' => I18nValidator\IsInt::class, - 'lessthan' => LessThan::class, - 'lessThan' => LessThan::class, - 'LessThan' => LessThan::class, - 'notempty' => NotEmpty::class, - 'notEmpty' => NotEmpty::class, - 'NotEmpty' => NotEmpty::class, - 'phonenumber' => I18nValidator\PhoneNumber::class, - 'phoneNumber' => I18nValidator\PhoneNumber::class, - 'PhoneNumber' => I18nValidator\PhoneNumber::class, - 'postcode' => I18nValidator\PostCode::class, - 'postCode' => I18nValidator\PostCode::class, - 'PostCode' => I18nValidator\PostCode::class, - 'regex' => Regex::class, - 'Regex' => Regex::class, - 'sitemapchangefreq' => Sitemap\Changefreq::class, - 'sitemapChangefreq' => Sitemap\Changefreq::class, - 'SitemapChangefreq' => Sitemap\Changefreq::class, - 'sitemaplastmod' => Sitemap\Lastmod::class, - 'sitemapLastmod' => Sitemap\Lastmod::class, - 'SitemapLastmod' => Sitemap\Lastmod::class, - 'sitemaploc' => Sitemap\Loc::class, - 'sitemapLoc' => Sitemap\Loc::class, - 'SitemapLoc' => Sitemap\Loc::class, - 'sitemappriority' => Sitemap\Priority::class, - 'sitemapPriority' => Sitemap\Priority::class, - 'SitemapPriority' => Sitemap\Priority::class, - 'stringlength' => StringLength::class, - 'stringLength' => StringLength::class, - 'StringLength' => StringLength::class, - 'step' => Step::class, - 'Step' => Step::class, - 'timezone' => Timezone::class, - 'Timezone' => Timezone::class, - 'uri' => Uri::class, - 'Uri' => Uri::class, - 'uuid' => Uuid::class, - 'Uuid' => Uuid::class, - - // Legacy Zend Framework aliases - Alnum::class => I18nValidator\Alnum::class, - Alpha::class => I18nValidator\Alpha::class, - \Zend\Validator\Barcode::class => Barcode::class, - \Zend\Validator\Between::class => Between::class, - \Zend\Validator\Bitwise::class => Bitwise::class, - \Zend\Validator\Callback::class => Callback::class, - \Zend\Validator\CreditCard::class => CreditCard::class, - \Zend\Validator\Csrf::class => Csrf::class, - \Zend\Validator\DateStep::class => DateStep::class, - \Zend\Validator\Date::class => Date::class, - DateTime::class => I18nValidator\DateTime::class, - NoRecordExists::class => Db\NoRecordExists::class, - RecordExists::class => Db\RecordExists::class, - \Zend\Validator\Digits::class => Digits::class, - \Zend\Validator\EmailAddress::class => EmailAddress::class, - \Zend\Validator\Explode::class => Explode::class, - Count::class => File\Count::class, - Crc32::class => File\Crc32::class, - ExcludeExtension::class => File\ExcludeExtension::class, - ExcludeMimeType::class => File\ExcludeMimeType::class, - Exists::class => File\Exists::class, - Extension::class => File\Extension::class, - FilesSize::class => File\FilesSize::class, - Hash::class => File\Hash::class, - ImageSize::class => File\ImageSize::class, - IsCompressed::class => File\IsCompressed::class, - IsImage::class => File\IsImage::class, - Md5::class => File\Md5::class, - MimeType::class => File\MimeType::class, - NotExists::class => File\NotExists::class, - Sha1::class => File\Sha1::class, - Size::class => File\Size::class, - Upload::class => File\Upload::class, - UploadFile::class => File\UploadFile::class, - WordCount::class => File\WordCount::class, - IsFloat::class => I18nValidator\IsFloat::class, - \Zend\Validator\GpsPoint::class => GpsPoint::class, - \Zend\Validator\GreaterThan::class => GreaterThan::class, - \Zend\Validator\Hex::class => Hex::class, - \Zend\Validator\Hostname::class => Hostname::class, - \Zend\Validator\Iban::class => Iban::class, - \Zend\Validator\Identical::class => Identical::class, - \Zend\Validator\InArray::class => InArray::class, - IsInt::class => I18nValidator\IsInt::class, - \Zend\Validator\Ip::class => Ip::class, - \Zend\Validator\Isbn::class => Isbn::class, - \Zend\Validator\IsInstanceOf::class => IsInstanceOf::class, - \Zend\Validator\LessThan::class => LessThan::class, - \Zend\Validator\NotEmpty::class => NotEmpty::class, - PhoneNumber::class => I18nValidator\PhoneNumber::class, - PostCode::class => I18nValidator\PostCode::class, - \Zend\Validator\Regex::class => Regex::class, - Changefreq::class => Sitemap\Changefreq::class, - Lastmod::class => Sitemap\Lastmod::class, - Loc::class => Sitemap\Loc::class, - Priority::class => Sitemap\Priority::class, - \Zend\Validator\StringLength::class => StringLength::class, - \Zend\Validator\Step::class => Step::class, - \Zend\Validator\Timezone::class => Timezone::class, - \Zend\Validator\Uri::class => Uri::class, - \Zend\Validator\Uuid::class => Uuid::class, - - // v2 normalized FQCNs - 'zendvalidatorbarcode' => Barcode::class, - 'zendvalidatorbetween' => Between::class, - 'zendvalidatorbitwise' => Bitwise::class, - 'zendvalidatorcallback' => Callback::class, - 'zendvalidatorcreditcard' => CreditCard::class, - 'zendvalidatorcsrf' => Csrf::class, - 'zendvalidatordatestep' => DateStep::class, - 'zendvalidatordate' => Date::class, - 'zendvalidatordbnorecordexists' => Db\NoRecordExists::class, - 'zendvalidatordbrecordexists' => Db\RecordExists::class, - 'zendvalidatordigits' => Digits::class, - 'zendvalidatoremailaddress' => EmailAddress::class, - 'zendvalidatorexplode' => Explode::class, - 'zendvalidatorfilecount' => File\Count::class, - 'zendvalidatorfilecrc32' => File\Crc32::class, - 'zendvalidatorfileexcludeextension' => File\ExcludeExtension::class, - 'zendvalidatorfileexcludemimetype' => File\ExcludeMimeType::class, - 'zendvalidatorfileexists' => File\Exists::class, - 'zendvalidatorfileextension' => File\Extension::class, - 'zendvalidatorfilefilessize' => File\FilesSize::class, - 'zendvalidatorfilehash' => File\Hash::class, - 'zendvalidatorfileimagesize' => File\ImageSize::class, - 'zendvalidatorfileiscompressed' => File\IsCompressed::class, - 'zendvalidatorfileisimage' => File\IsImage::class, - 'zendvalidatorfilemd5' => File\Md5::class, - 'zendvalidatorfilemimetype' => File\MimeType::class, - 'zendvalidatorfilenotexists' => File\NotExists::class, - 'zendvalidatorfilesha1' => File\Sha1::class, - 'zendvalidatorfilesize' => File\Size::class, - 'zendvalidatorfileupload' => File\Upload::class, - 'zendvalidatorfileuploadfile' => File\UploadFile::class, - 'zendvalidatorfilewordcount' => File\WordCount::class, - 'zendvalidatorgpspoint' => GpsPoint::class, - 'zendvalidatorgreaterthan' => GreaterThan::class, - 'zendvalidatorhex' => Hex::class, - 'zendvalidatorhostname' => Hostname::class, - 'zendi18nvalidatoralnum' => I18nValidator\Alnum::class, - 'zendi18nvalidatoralpha' => I18nValidator\Alpha::class, - 'zendi18nvalidatordatetime' => I18nValidator\DateTime::class, - 'zendi18nvalidatorisfloat' => I18nValidator\IsFloat::class, - 'zendi18nvalidatorisint' => I18nValidator\IsInt::class, - 'zendi18nvalidatorphonenumber' => I18nValidator\PhoneNumber::class, - 'zendi18nvalidatorpostcode' => I18nValidator\PostCode::class, - 'zendvalidatoriban' => Iban::class, - 'zendvalidatoridentical' => Identical::class, - 'zendvalidatorinarray' => InArray::class, - 'zendvalidatorip' => Ip::class, - 'zendvalidatorisbn' => Isbn::class, - 'zendvalidatorisinstanceof' => IsInstanceOf::class, - 'zendvalidatorlessthan' => LessThan::class, - 'zendvalidatornotempty' => NotEmpty::class, - 'zendvalidatorregex' => Regex::class, - 'zendvalidatorsitemapchangefreq' => Sitemap\Changefreq::class, - 'zendvalidatorsitemaplastmod' => Sitemap\Lastmod::class, - 'zendvalidatorsitemaploc' => Sitemap\Loc::class, - 'zendvalidatorsitemappriority' => Sitemap\Priority::class, - 'zendvalidatorstringlength' => StringLength::class, - 'zendvalidatorstep' => Step::class, - 'zendvalidatortimezone' => Timezone::class, - 'zendvalidatoruri' => Uri::class, - 'zendvalidatoruuid' => Uuid::class, - ]; - - /** - * Default set of factories - * - * @var FactoriesConfigurationType - */ - protected $factories = [ - I18nValidator\Alnum::class => InvokableFactory::class, - I18nValidator\Alpha::class => InvokableFactory::class, - Barcode::class => InvokableFactory::class, - Between::class => InvokableFactory::class, - Bitwise::class => InvokableFactory::class, - BusinessIdentifierCode::class => InvokableFactory::class, - Callback::class => InvokableFactory::class, - CreditCard::class => InvokableFactory::class, - Csrf::class => InvokableFactory::class, - DateStep::class => InvokableFactory::class, - Date::class => InvokableFactory::class, - I18nValidator\DateTime::class => InvokableFactory::class, - Db\NoRecordExists::class => InvokableFactory::class, - Db\RecordExists::class => InvokableFactory::class, - Digits::class => InvokableFactory::class, - EmailAddress::class => InvokableFactory::class, - Explode::class => InvokableFactory::class, - File\Count::class => InvokableFactory::class, - File\Crc32::class => InvokableFactory::class, - File\ExcludeExtension::class => InvokableFactory::class, - File\ExcludeMimeType::class => InvokableFactory::class, - File\Exists::class => InvokableFactory::class, - File\Extension::class => InvokableFactory::class, - File\FilesSize::class => InvokableFactory::class, - File\Hash::class => InvokableFactory::class, - File\ImageSize::class => InvokableFactory::class, - File\IsCompressed::class => InvokableFactory::class, - File\IsImage::class => InvokableFactory::class, - File\Md5::class => InvokableFactory::class, - File\MimeType::class => InvokableFactory::class, - File\NotExists::class => InvokableFactory::class, - File\Sha1::class => InvokableFactory::class, - File\Size::class => InvokableFactory::class, - File\Upload::class => InvokableFactory::class, - File\UploadFile::class => InvokableFactory::class, - File\WordCount::class => InvokableFactory::class, - I18nValidator\IsFloat::class => InvokableFactory::class, - GpsPoint::class => InvokableFactory::class, - GreaterThan::class => InvokableFactory::class, - Hex::class => InvokableFactory::class, - Hostname::class => InvokableFactory::class, - Iban::class => InvokableFactory::class, - Identical::class => InvokableFactory::class, - InArray::class => InvokableFactory::class, - I18nValidator\IsInt::class => InvokableFactory::class, - Ip::class => InvokableFactory::class, - Isbn::class => InvokableFactory::class, - IsCountable::class => InvokableFactory::class, - IsInstanceOf::class => InvokableFactory::class, - LessThan::class => InvokableFactory::class, - NotEmpty::class => InvokableFactory::class, - I18nValidator\PhoneNumber::class => InvokableFactory::class, - I18nValidator\PostCode::class => InvokableFactory::class, - Regex::class => InvokableFactory::class, - Sitemap\Changefreq::class => InvokableFactory::class, - Sitemap\Lastmod::class => InvokableFactory::class, - Sitemap\Loc::class => InvokableFactory::class, - Sitemap\Priority::class => InvokableFactory::class, - StringLength::class => InvokableFactory::class, - Step::class => InvokableFactory::class, - Timezone::class => InvokableFactory::class, - Uri::class => InvokableFactory::class, - Uuid::class => InvokableFactory::class, - - // v2 canonical FQCNs - 'laminasvalidatorbarcodecode25interleaved' => InvokableFactory::class, - 'laminasvalidatorbarcodecode25' => InvokableFactory::class, - 'laminasvalidatorbarcodecode39ext' => InvokableFactory::class, - 'laminasvalidatorbarcodecode39' => InvokableFactory::class, - 'laminasvalidatorbarcodecode93ext' => InvokableFactory::class, - 'laminasvalidatorbarcodecode93' => InvokableFactory::class, - 'laminasvalidatorbarcodeean12' => InvokableFactory::class, - 'laminasvalidatorbarcodeean13' => InvokableFactory::class, - 'laminasvalidatorbarcodeean14' => InvokableFactory::class, - 'laminasvalidatorbarcodeean18' => InvokableFactory::class, - 'laminasvalidatorbarcodeean2' => InvokableFactory::class, - 'laminasvalidatorbarcodeean5' => InvokableFactory::class, - 'laminasvalidatorbarcodeean8' => InvokableFactory::class, - 'laminasvalidatorbarcodegtin12' => InvokableFactory::class, - 'laminasvalidatorbarcodegtin13' => InvokableFactory::class, - 'laminasvalidatorbarcodegtin14' => InvokableFactory::class, - 'laminasvalidatorbarcodeidentcode' => InvokableFactory::class, - 'laminasvalidatorbarcodeintelligentmail' => InvokableFactory::class, - 'laminasvalidatorbarcodeissn' => InvokableFactory::class, - 'laminasvalidatorbarcodeitf14' => InvokableFactory::class, - 'laminasvalidatorbarcodeleitcode' => InvokableFactory::class, - 'laminasvalidatorbarcodeplanet' => InvokableFactory::class, - 'laminasvalidatorbarcodepostnet' => InvokableFactory::class, - 'laminasvalidatorbarcoderoyalmail' => InvokableFactory::class, - 'laminasvalidatorbarcodesscc' => InvokableFactory::class, - 'laminasvalidatorbarcodeupca' => InvokableFactory::class, - 'laminasvalidatorbarcodeupce' => InvokableFactory::class, - 'laminasvalidatorbarcode' => InvokableFactory::class, - 'laminasvalidatorbetween' => InvokableFactory::class, - 'laminasvalidatorbitwise' => InvokableFactory::class, - 'laminasvalidatorcallback' => InvokableFactory::class, - 'laminasvalidatorcreditcard' => InvokableFactory::class, - 'laminasvalidatorcsrf' => InvokableFactory::class, - 'laminasvalidatordatestep' => InvokableFactory::class, - 'laminasvalidatordate' => InvokableFactory::class, - 'laminasvalidatordbnorecordexists' => InvokableFactory::class, - 'laminasvalidatordbrecordexists' => InvokableFactory::class, - 'laminasvalidatordigits' => InvokableFactory::class, - 'laminasvalidatoremailaddress' => InvokableFactory::class, - 'laminasvalidatorexplode' => InvokableFactory::class, - 'laminasvalidatorfilecount' => InvokableFactory::class, - 'laminasvalidatorfilecrc32' => InvokableFactory::class, - 'laminasvalidatorfileexcludeextension' => InvokableFactory::class, - 'laminasvalidatorfileexcludemimetype' => InvokableFactory::class, - 'laminasvalidatorfileexists' => InvokableFactory::class, - 'laminasvalidatorfileextension' => InvokableFactory::class, - 'laminasvalidatorfilefilessize' => InvokableFactory::class, - 'laminasvalidatorfilehash' => InvokableFactory::class, - 'laminasvalidatorfileimagesize' => InvokableFactory::class, - 'laminasvalidatorfileiscompressed' => InvokableFactory::class, - 'laminasvalidatorfileisimage' => InvokableFactory::class, - 'laminasvalidatorfilemd5' => InvokableFactory::class, - 'laminasvalidatorfilemimetype' => InvokableFactory::class, - 'laminasvalidatorfilenotexists' => InvokableFactory::class, - 'laminasvalidatorfilesha1' => InvokableFactory::class, - 'laminasvalidatorfilesize' => InvokableFactory::class, - 'laminasvalidatorfileupload' => InvokableFactory::class, - 'laminasvalidatorfileuploadfile' => InvokableFactory::class, - 'laminasvalidatorfilewordcount' => InvokableFactory::class, - 'laminasvalidatorgpspoint' => InvokableFactory::class, - 'laminasvalidatorgreaterthan' => InvokableFactory::class, - 'laminasvalidatorhex' => InvokableFactory::class, - 'laminasvalidatorhostname' => InvokableFactory::class, - 'laminasi18nvalidatoralnum' => InvokableFactory::class, - 'laminasi18nvalidatoralpha' => InvokableFactory::class, - 'laminasi18nvalidatordatetime' => InvokableFactory::class, - 'laminasi18nvalidatorisfloat' => InvokableFactory::class, - 'laminasi18nvalidatorisint' => InvokableFactory::class, - 'laminasi18nvalidatorphonenumber' => InvokableFactory::class, - 'laminasi18nvalidatorpostcode' => InvokableFactory::class, - 'laminasvalidatoriban' => InvokableFactory::class, - 'laminasvalidatoridentical' => InvokableFactory::class, - 'laminasvalidatorinarray' => InvokableFactory::class, - 'laminasvalidatorip' => InvokableFactory::class, - 'laminasvalidatorisbn' => InvokableFactory::class, - 'laminasvalidatoriscountable' => InvokableFactory::class, - 'laminasvalidatorisinstanceof' => InvokableFactory::class, - 'laminasvalidatorlessthan' => InvokableFactory::class, - 'laminasvalidatornotempty' => InvokableFactory::class, - 'laminasvalidatorregex' => InvokableFactory::class, - 'laminasvalidatorsitemapchangefreq' => InvokableFactory::class, - 'laminasvalidatorsitemaplastmod' => InvokableFactory::class, - 'laminasvalidatorsitemaploc' => InvokableFactory::class, - 'laminasvalidatorsitemappriority' => InvokableFactory::class, - 'laminasvalidatorstringlength' => InvokableFactory::class, - 'laminasvalidatorstep' => InvokableFactory::class, - 'laminasvalidatortimezone' => InvokableFactory::class, - 'laminasvalidatoruri' => InvokableFactory::class, - 'laminasvalidatoruuid' => InvokableFactory::class, - ]; - - /** - * Whether or not to share by default; default to false (v2) - * - * @var bool - */ - protected $shareByDefault = false; - - /** - * Whether or not to share by default; default to false (v3) - * - * @var bool - */ - protected $sharedByDefault = false; - - /** - * Default instance type - * - * @var string - */ - protected $instanceOf = ValidatorInterface::class; - - /** - * Constructor - * - * After invoking parent constructor, add an initializer to inject the - * attached translator, if any, to the currently requested helper. - * - * {@inheritDoc} - * - * @param ServiceManagerConfiguration $v3config - */ - public function __construct($configOrContainerInstance = null, array $v3config = []) - { - parent::__construct($configOrContainerInstance, $v3config); - - $this->addInitializer([$this, 'injectTranslator']); - $this->addInitializer([$this, 'injectValidatorPluginManager']); - } - - /** - * Validate plugin instance - * - * {@inheritDoc} - * - * @param mixed $instance - * @psalm-assert InstanceType $instance - */ - public function validate($instance) - { - if (! $instance instanceof $this->instanceOf) { - throw new InvalidServiceException(sprintf( - '%s expects only to create instances of %s; %s is invalid', - static::class, - $this->instanceOf, - get_debug_type($instance) - )); - } - } - - /** - * For v2 compatibility: validate plugin instance. - * - * Proxies to `validate()`. - * - * @return void - * @throws Exception\RuntimeException - */ - public function validatePlugin(mixed $plugin) - { - try { - $this->validate($plugin); - } catch (InvalidServiceException $e) { - throw new Exception\RuntimeException(sprintf( - 'Plugin of type %s is invalid; must implement %s', - get_debug_type($plugin), - ValidatorInterface::class - ), $e->getCode(), $e); - } - } - - /** - * Inject a validator instance with the registered translator - * - * @param ContainerInterface|object $first - * @param ContainerInterface|object $second - * @return void - */ - public function injectTranslator($first, $second) - { - if ($first instanceof ContainerInterface) { - $container = $first; - $validator = $second; - } else { - $container = $second; - $validator = $first; - } - - // V2 means we pull it from the parent container - if ($container === $this && method_exists($container, 'getServiceLocator') && $container->getServiceLocator()) { - $container = $container->getServiceLocator(); - } - - if ($validator instanceof Translator\TranslatorAwareInterface) { - if ($container && $container->has('MvcTranslator')) { - $validator->setTranslator($container->get('MvcTranslator')); - } - } - } - - /** - * Inject a validator plugin manager - * - * @param ContainerInterface|object $first - * @param ContainerInterface|object $second - * @return void - */ - public function injectValidatorPluginManager($first, $second) - { - if ($first instanceof ContainerInterface) { - $validator = $second; - } else { - $validator = $first; - } - if ($validator instanceof ValidatorPluginManagerAwareInterface) { - $validator->setValidatorPluginManager($this); - } - } -} diff --git a/lib/laminas/laminas-validator/src/ValidatorPluginManagerAwareInterface.php b/lib/laminas/laminas-validator/src/ValidatorPluginManagerAwareInterface.php deleted file mode 100644 index d30cc7e79..000000000 --- a/lib/laminas/laminas-validator/src/ValidatorPluginManagerAwareInterface.php +++ /dev/null @@ -1,18 +0,0 @@ -has('ServiceListener')) { - return $pluginManager; - } - - // If we do not have a config service, nothing more to do - if (! $container->has('config')) { - return $pluginManager; - } - - $config = $container->get('config'); - - // If we do not have validators configuration, nothing more to do - if (! isset($config['validators']) || ! is_array($config['validators'])) { - return $pluginManager; - } - - // Wire service configuration for validators - (new Config($config['validators']))->configureServiceManager($pluginManager); - - return $pluginManager; - } - - /** - * {@inheritDoc} - * - * @param string|null $name - * @param string|null $requestedName - * @return ValidatorPluginManager - */ - public function createService(ServiceLocatorInterface $container, $name = null, $requestedName = null) - { - return $this($container, $requestedName ?: ValidatorPluginManager::class, $this->creationOptions); - } - - /** - * laminas-servicemanager v2 support for invocation options. - * - * @param ServiceManagerConfiguration $options - * @return void - */ - public function setCreationOptions(array $options) - { - $this->creationOptions = $options; - } -} diff --git a/lib/laminas/laminas-validator/src/ValidatorProviderInterface.php b/lib/laminas/laminas-validator/src/ValidatorProviderInterface.php deleted file mode 100644 index fc6fbb298..000000000 --- a/lib/laminas/laminas-validator/src/ValidatorProviderInterface.php +++ /dev/null @@ -1,24 +0,0 @@ - + + + + + + + + + + + + + test + + + + + + + + + + src + + + + + + + + diff --git a/lib/league/oauth2-client/src/Token/SettableRefreshTokenInterface.php b/lib/league/oauth2-client/src/Token/SettableRefreshTokenInterface.php new file mode 100644 index 000000000..491bee991 --- /dev/null +++ b/lib/league/oauth2-client/src/Token/SettableRefreshTokenInterface.php @@ -0,0 +1,26 @@ + + * @license http://opensource.org/licenses/MIT MIT + * @link http://thephpleague.com/oauth2-client/ Documentation + * @link https://packagist.org/packages/league/oauth2-client Packagist + * @link https://github.com/thephpleague/oauth2-client GitHub + */ + +namespace League\OAuth2\Client\Token; + +interface SettableRefreshTokenInterface +{ + /** + * Sets or replaces the refresh token with the provided refresh token. + * + * @param string $refreshToken + * @return void + */ + public function setRefreshToken($refreshToken); +} diff --git a/lib/pelago/emogrifier/src/HtmlProcessor/CssVariableEvaluator.php b/lib/pelago/emogrifier/src/HtmlProcessor/CssVariableEvaluator.php new file mode 100644 index 000000000..9adf0b9ce --- /dev/null +++ b/lib/pelago/emogrifier/src/HtmlProcessor/CssVariableEvaluator.php @@ -0,0 +1,200 @@ + + */ + private $currentVariableDefinitions = []; + + /** + * Replaces all CSS custom property references in inline style attributes with their corresponding values where + * defined in inline style attributes (either from the element itself or the nearest ancestor). + * + * @return $this + * + * @throws \UnexpectedValueException + */ + public function evaluateVariables(): self + { + return $this->evaluateVariablesInElementAndDescendants($this->getHtmlElement(), []); + } + + /** + * @param array $declarations + * + * @return array + */ + private function getVariableDefinitionsFromDeclarations(array $declarations): array + { + return \array_filter( + $declarations, + static function (string $key): bool { + return \substr($key, 0, 2) === '--'; + }, + ARRAY_FILTER_USE_KEY + ); + } + + /** + * Callback function for {@see replaceVariablesInPropertyValue} performing regular expression replacement. + * + * @param array $matches + */ + private function getPropertyValueReplacement(array $matches): string + { + $variableName = $matches[1]; + + if (isset($this->currentVariableDefinitions[$variableName])) { + $variableValue = $this->currentVariableDefinitions[$variableName]; + } else { + $fallbackValueSeparator = $matches[2] ?? ''; + if ($fallbackValueSeparator !== '') { + $fallbackValue = $matches[3]; + // The fallback value may use other CSS variables, so recurse + $variableValue = $this->replaceVariablesInPropertyValue($fallbackValue); + } else { + $variableValue = $matches[0]; + } + } + + return $variableValue; + } + + /** + * Regular expression based on {@see https://stackoverflow.com/a/54143883/2511031 a StackOverflow answer}. + */ + private function replaceVariablesInPropertyValue(string $propertyValue): string + { + return (new Preg())->replaceCallback( + '/ + var\\( + \\s*+ + # capture variable name including `--` prefix + ( + --[^\\s\\),]++ + ) + \\s*+ + # capture optional fallback value + (?: + # capture separator to confirm there is a fallback value + (,)\\s* + # begin capture with named group that can be used recursively + (? + # begin named group to match sequence without parentheses, except in strings + (? + # repeated zero or more times: + (?: + # sequence without parentheses or quotes + [^\\(\\)\'"]++ + | + # string in double quotes + "(?>[^"\\\\]++|\\\\.)*" + | + # string in single quotes + \'(?>[^\'\\\\]++|\\\\.)*\' + )*+ + ) + # repeated zero or more times: + (?: + # sequence in parentheses + \\( + # using the named recursable pattern + (?&recursable) + \\) + # sequence without parentheses, except in strings + (?&noparentheses) + )*+ + ) + )?+ + \\) + /x', + \Closure::fromCallable([$this, 'getPropertyValueReplacement']), + $propertyValue + ); + } + + /** + * @param array $declarations + * + * @return ?array `null` is returned if no substitutions were made. + */ + private function replaceVariablesInDeclarations(array $declarations): ?array + { + $substitutionsMade = false; + $result = \array_map( + function (string $propertyValue) use (&$substitutionsMade): string { + $newPropertyValue = $this->replaceVariablesInPropertyValue($propertyValue); + if ($newPropertyValue !== $propertyValue) { + $substitutionsMade = true; + } + return $newPropertyValue; + }, + $declarations + ); + + return $substitutionsMade ? $result : null; + } + + /** + * @param array $declarations + */ + private function getDeclarationsAsString(array $declarations): string + { + $declarationStrings = \array_map( + static function (string $key, string $value): string { + return $key . ': ' . $value; + }, + \array_keys($declarations), + \array_values($declarations) + ); + + return \implode('; ', $declarationStrings) . ';'; + } + + /** + * @param array $ancestorVariableDefinitions + * + * @return $this + */ + private function evaluateVariablesInElementAndDescendants( + \DOMElement $element, + array $ancestorVariableDefinitions + ): self { + $style = $element->getAttribute('style'); + + // Avoid parsing declarations if none use or define a variable + if ((new Preg())->match('/(?parse($style); + $variableDefinitions = $this->currentVariableDefinitions + = $this->getVariableDefinitionsFromDeclarations($declarations) + $ancestorVariableDefinitions; + + $newDeclarations = $this->replaceVariablesInDeclarations($declarations); + if ($newDeclarations !== null) { + $element->setAttribute('style', $this->getDeclarationsAsString($newDeclarations)); + } + } else { + $variableDefinitions = $ancestorVariableDefinitions; + } + + foreach ($element->childNodes as $child) { + if ($child instanceof \DOMElement) { + $this->evaluateVariablesInElementAndDescendants($child, $variableDefinitions); + } + } + + return $this; + } +} diff --git a/lib/pelago/emogrifier/src/Utilities/DeclarationBlockParser.php b/lib/pelago/emogrifier/src/Utilities/DeclarationBlockParser.php new file mode 100644 index 000000000..7de5978d7 --- /dev/null +++ b/lib/pelago/emogrifier/src/Utilities/DeclarationBlockParser.php @@ -0,0 +1,96 @@ +> + */ + private static $cache = []; + + /** + * CSS custom properties (variables) have case-sensitive names, so their case must be preserved. + * Standard CSS properties have case-insensitive names, which are converted to lowercase. + * + * @param non-empty-string $name + * + * @return non-empty-string + */ + public function normalizePropertyName(string $name): string + { + if (\substr($name, 0, 2) === '--') { + return $name; + } else { + return \strtolower($name); + } + } + + /** + * Parses a CSS declaration block into property name/value pairs. + * + * Example: + * + * The declaration block + * + * "color: #000; font-weight: bold;" + * + * will be parsed into the following array: + * + * "color" => "#000" + * "font-weight" => "bold" + * + * @param string $declarationBlock the CSS declarations block without the curly braces, may be empty + * + * @return array + * the CSS declarations with the property names as array keys and the property values as array values + * + * @throws \UnexpectedValueException if an empty property name is encountered (which cannot happen) + */ + public function parse(string $declarationBlock): array + { + if (isset(self::$cache[$declarationBlock])) { + return self::$cache[$declarationBlock]; + } + + $preg = new Preg(); + + $declarations = $preg->split('/;(?!base64|charset)/', $declarationBlock); + + $properties = []; + foreach ($declarations as $declaration) { + $matches = []; + if ( + $preg->match( + '/^([A-Za-z\\-]+)\\s*:\\s*(.+)$/s', + \trim($declaration), + $matches + ) + === 0 + ) { + continue; + } + + $propertyName = $matches[1]; + if ($propertyName === '') { + // This cannot happen since the regular epression matches one or more characters. + throw new \UnexpectedValueException('An empty property name was encountered.', 1727046409); + } + $propertyValue = $matches[2]; + $properties[$this->normalizePropertyName($propertyName)] = $propertyValue; + } + self::$cache[$declarationBlock] = $properties; + + return $properties; + } +} diff --git a/lib/pelago/emogrifier/src/Utilities/Preg.php b/lib/pelago/emogrifier/src/Utilities/Preg.php new file mode 100644 index 000000000..592f519ba --- /dev/null +++ b/lib/pelago/emogrifier/src/Utilities/Preg.php @@ -0,0 +1,202 @@ +throwExceptions = $throw; + + return $this; + } + + /** + * Wraps `preg_replace`, though does not support `$subject` being an array. + * If an error occurs, and exceptions are not being thrown, the original `$subject` is returned. + * + * @param non-empty-string|non-empty-array $pattern + * @param string|non-empty-array $replacement + * + * @throws \RuntimeException + */ + public function replace($pattern, $replacement, string $subject, int $limit = -1, ?int &$count = null): string + { + $result = \preg_replace($pattern, $replacement, $subject, $limit, $count); + + if ($result === null) { + $this->logOrThrowPregLastError(); + $result = $subject; + } + + return $result; + } + + /** + * Wraps `preg_replace_callback`, though does not support `$subject` being an array. + * If an error occurs, and exceptions are not being thrown, the original `$subject` is returned. + * + * Note that (unlike when calling `preg_replace_callback`), `$callback` cannot be a non-public method + * represented by an array comprising an object or class name and the method name. + * To circumvent that, use `\Closure::fromCallable([$objectOrClassName, 'method'])`. + * + * @param non-empty-string|non-empty-array $pattern + * + * @throws \RuntimeException + */ + public function replaceCallback( + $pattern, + callable $callback, + string $subject, + int $limit = -1, + ?int &$count = null + ): string { + $result = \preg_replace_callback($pattern, $callback, $subject, $limit, $count); + + if ($result === null) { + $this->logOrThrowPregLastError(); + $result = $subject; + } + + return $result; + } + + /** + * Wraps `preg_split`. + * If an error occurs, and exceptions are not being thrown, + * a single-element array containing the original `$subject` is returned. + * This method does not support the `PREG_SPLIT_OFFSET_CAPTURE` flag and will throw an exception if it is specified. + * + * @param non-empty-string $pattern + * + * @return array + * + * @throws \RuntimeException + */ + public function split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array + { + if (($flags & PREG_SPLIT_OFFSET_CAPTURE) !== 0) { + throw new \RuntimeException('PREG_SPLIT_OFFSET_CAPTURE is not supported by Preg::split', 1726506348); + } + + $result = \preg_split($pattern, $subject, $limit, $flags); + + if ($result === false) { + $this->logOrThrowPregLastError(); + $result = [$subject]; + } + + return $result; + } + + /** + * Wraps `preg_match`. + * If an error occurs, and exceptions are not being thrown, + * zero (`0`) is returned, and if the `$matches` parameter is provided, it is set to an empty array. + * This method does not currently support the `$flags` or `$offset` parameters. + * + * @param non-empty-string $pattern + * @param array $matches + * + * @return 0|1 + * + * @throws \RuntimeException + */ + public function match(string $pattern, string $subject, ?array &$matches = null): int + { + $result = \preg_match($pattern, $subject, $matches); + + if ($result === false) { + $this->logOrThrowPregLastError(); + $result = 0; + $matches = []; + } + + return $result; + } + + /** + * Wraps `preg_match_all`. + * + * If an error occurs, and exceptions are not being thrown, zero (`0`) is returned. + * + * In the error case, if the `$matches` parameter is provided, it is set to an array containing empty arrays for the + * full pattern match and any possible subpattern match that might be expected. + * The algorithm to determine the length of this array simply counts the number of opening parentheses in the + * `$pattern`, which may result in a longer array than expected, but guarantees that it is at least as long as + * expected. + * + * This method does not currently support the `$flags` or `$offset` parameters. + * + * @param non-empty-string $pattern + * @param array> $matches + * + * @throws \RuntimeException + */ + public function matchAll(string $pattern, string $subject, ?array &$matches = null): int + { + $result = \preg_match_all($pattern, $subject, $matches); + + if ($result === false) { + $this->logOrThrowPregLastError(); + $result = 0; + $matches = \array_fill(0, \substr_count($pattern, '(') + 1, []); + } + + return $result; + } + + /** + * Obtains the name of the error constant for `preg_last_error` + * (based on code posted at {@see https://www.php.net/manual/en/function.preg-last-error.php#124124}) + * and puts it into an error message which is either passed to `trigger_error` + * or used in the exception which is thrown (depending on the `$throwExceptions` property). + * + * @throws \RuntimeException + */ + private function logOrThrowPregLastError(): void + { + $pcreConstants = \get_defined_constants(true)['pcre']; + $pcreErrorConstantNames = \array_flip(\array_filter( + $pcreConstants, + static function (string $key): bool { + return \substr($key, -6) === '_ERROR'; + }, + ARRAY_FILTER_USE_KEY + )); + + $pregLastError = \preg_last_error(); + $message = 'PCRE regex execution error `' . (string) ($pcreErrorConstantNames[$pregLastError] ?? $pregLastError) + . '`'; + + if ($this->throwExceptions) { + throw new \RuntimeException($message, 1592870147); + } + \trigger_error($message); + } +} diff --git a/lib/sabberworm/php-css-parser/src/CSSElement.php b/lib/sabberworm/php-css-parser/src/CSSElement.php new file mode 100644 index 000000000..944aabe2c --- /dev/null +++ b/lib/sabberworm/php-css-parser/src/CSSElement.php @@ -0,0 +1,17 @@ +iPosition = $iPosition; + $this->oParserState = $oParserState; + } + + /** + * @return void + */ + public function backtrack() + { + $this->oParserState->setPosition($this->iPosition); + } +} diff --git a/lib/sabberworm/php-css-parser/src/Position/Position.php b/lib/sabberworm/php-css-parser/src/Position/Position.php new file mode 100644 index 000000000..1c4d0df02 --- /dev/null +++ b/lib/sabberworm/php-css-parser/src/Position/Position.php @@ -0,0 +1,72 @@ +|null + */ + protected $lineNumber; + + /** + * @var int<0, max>|null + */ + protected $columnNumber; + + /** + * @return int<1, max>|null + */ + public function getLineNumber() + { + return $this->lineNumber; + } + + /** + * @return int<0, max> + */ + public function getLineNo() + { + $lineNumber = $this->getLineNumber(); + + return $lineNumber !== null ? $lineNumber : 0; + } + + /** + * @return int<0, max>|null + */ + public function getColumnNumber() + { + return $this->columnNumber; + } + + /** + * @return int<0, max> + */ + public function getColNo() + { + $columnNumber = $this->getColumnNumber(); + + return $columnNumber !== null ? $columnNumber : 0; + } + + /** + * @param int<0, max>|null $lineNumber + * @param int<0, max>|null $columnNumber + */ + public function setPosition($lineNumber, $columnNumber = null) + { + // The conditional is for backwards compatibility (backcompat); `0` will not be allowed in future. + $this->lineNumber = $lineNumber !== 0 ? $lineNumber : null; + $this->columnNumber = $columnNumber; + } +} diff --git a/lib/sabberworm/php-css-parser/src/Position/Positionable.php b/lib/sabberworm/php-css-parser/src/Position/Positionable.php new file mode 100644 index 000000000..4539c4251 --- /dev/null +++ b/lib/sabberworm/php-css-parser/src/Position/Positionable.php @@ -0,0 +1,45 @@ +|null + */ + public function getLineNumber(); + + /** + * @return int<0, max> + * + * @deprecated in version 8.9.0, will be removed in v9.0. Use `getLineNumber()` instead. + */ + public function getLineNo(); + + /** + * @return int<0, max>|null + */ + public function getColumnNumber(); + + /** + * @return int<0, max> + * + * @deprecated in version 8.9.0, will be removed in v9.0. Use `getColumnNumber()` instead. + */ + public function getColNo(); + + /** + * @param int<0, max>|null $lineNumber + * Providing zero for this parameter is deprecated in version 8.9.0, and will not be supported from v9.0. + * Use `null` instead when no line number is available. + * @param int<0, max>|null $columnNumber + */ + public function setPosition($lineNumber, $columnNumber = null); +} diff --git a/lib/symfony/deprecation-contracts/composer.json b/lib/symfony/deprecation-contracts/composer.json index c6d02d874..5533b5c3f 100644 --- a/lib/symfony/deprecation-contracts/composer.json +++ b/lib/symfony/deprecation-contracts/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.6-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/lib/symfony/event-dispatcher-contracts/EventDispatcherInterface.php b/lib/symfony/event-dispatcher-contracts/EventDispatcherInterface.php index 610d6ac06..2d7840d32 100644 --- a/lib/symfony/event-dispatcher-contracts/EventDispatcherInterface.php +++ b/lib/symfony/event-dispatcher-contracts/EventDispatcherInterface.php @@ -29,5 +29,5 @@ interface EventDispatcherInterface extends PsrEventDispatcherInterface * * @return T The passed $event MUST be returned */ - public function dispatch(object $event, string $eventName = null): object; + public function dispatch(object $event, ?string $eventName = null): object; } diff --git a/lib/symfony/event-dispatcher-contracts/composer.json b/lib/symfony/event-dispatcher-contracts/composer.json index 3618d53e9..d156b44b0 100644 --- a/lib/symfony/event-dispatcher-contracts/composer.json +++ b/lib/symfony/event-dispatcher-contracts/composer.json @@ -25,7 +25,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.6-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/lib/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php b/lib/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php index e25a664d2..2faea0463 100644 --- a/lib/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php +++ b/lib/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php @@ -43,7 +43,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa private ?RequestStack $requestStack; private string $currentRequestHash = ''; - public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null, RequestStack $requestStack = null) + public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, ?LoggerInterface $logger = null, ?RequestStack $requestStack = null) { $this->dispatcher = $dispatcher; $this->stopwatch = $stopwatch; @@ -93,7 +93,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa $this->dispatcher->removeSubscriber($subscriber); } - public function getListeners(string $eventName = null): array + public function getListeners(?string $eventName = null): array { return $this->dispatcher->getListeners($eventName); } @@ -113,12 +113,12 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa return $this->dispatcher->getListenerPriority($eventName, $listener); } - public function hasListeners(string $eventName = null): bool + public function hasListeners(?string $eventName = null): bool { return $this->dispatcher->hasListeners($eventName); } - public function dispatch(object $event, string $eventName = null): object + public function dispatch(object $event, ?string $eventName = null): object { $eventName ??= $event::class; @@ -127,7 +127,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa $currentRequestHash = $this->currentRequestHash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : ''; if (null !== $this->logger && $event instanceof StoppableEventInterface && $event->isPropagationStopped()) { - $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName)); + $this->logger->debug(\sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName)); } $this->preProcess($eventName); @@ -153,7 +153,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa return $event; } - public function getCalledListeners(Request $request = null): array + public function getCalledListeners(?Request $request = null): array { if (null === $this->callStack) { return []; @@ -171,7 +171,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa return $called; } - public function getNotCalledListeners(Request $request = null): array + public function getNotCalledListeners(?Request $request = null): array { try { $allListeners = $this->dispatcher instanceof EventDispatcher ? $this->getListenersWithPriority() : $this->getListenersWithoutPriority(); @@ -213,7 +213,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa return $notCalled; } - public function getOrphanedEvents(Request $request = null): array + public function getOrphanedEvents(?Request $request = null): array { if ($request) { return $this->orphanedEvents[spl_object_hash($request)] ?? []; @@ -279,7 +279,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa $this->wrappedListeners[$eventName][] = $wrappedListener; $this->dispatcher->removeListener($eventName, $listener); $this->dispatcher->addListener($eventName, $wrappedListener, $priority); - $this->callStack->attach($wrappedListener, [$eventName, $this->currentRequestHash]); + $this->callStack[$wrappedListener] = [$eventName, $this->currentRequestHash]; } } @@ -303,7 +303,7 @@ class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterfa if ($listener->wasCalled()) { $this->logger?->debug('Notified event "{event}" to listener "{listener}".', $context); } else { - $this->callStack->detach($listener); + unset($this->callStack[$listener]); } if (null !== $this->logger && $skipped) { diff --git a/lib/symfony/event-dispatcher/Debug/WrappedListener.php b/lib/symfony/event-dispatcher/Debug/WrappedListener.php index 6e0de1dff..59f7c1362 100644 --- a/lib/symfony/event-dispatcher/Debug/WrappedListener.php +++ b/lib/symfony/event-dispatcher/Debug/WrappedListener.php @@ -34,7 +34,7 @@ final class WrappedListener private ?int $priority = null; private static bool $hasClassStub; - public function __construct(callable|array $listener, ?string $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null, int $priority = null) + public function __construct(callable|array $listener, ?string $name, Stopwatch $stopwatch, ?EventDispatcherInterface $dispatcher = null, ?int $priority = null) { $this->listener = $listener; $this->optimizedListener = $listener instanceof \Closure ? $listener : (\is_callable($listener) ? $listener(...) : null); @@ -48,7 +48,7 @@ final class WrappedListener $this->callableRef .= '::'.$listener[1]; } elseif ($listener instanceof \Closure) { $r = new \ReflectionFunction($listener); - if (str_contains($r->name, '{closure}')) { + if (str_contains($r->name, '{closure')) { $this->pretty = $this->name = 'closure'; } elseif ($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) { $this->name = $class->name; diff --git a/lib/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php b/lib/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php index 866f4e64f..db119bb2f 100644 --- a/lib/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php +++ b/lib/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php @@ -91,7 +91,7 @@ class RegisterListenersPass implements CompilerPassInterface if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method'])) { if (!$r->hasMethod('__invoke')) { - throw new InvalidArgumentException(sprintf('None of the "%s" or "__invoke" methods exist for the service "%s". Please define the "method" attribute on "kernel.event_listener" tags.', $event['method'], $id)); + throw new InvalidArgumentException(\sprintf('None of the "%s" or "__invoke" methods exist for the service "%s". Please define the "method" attribute on "kernel.event_listener" tags.', $event['method'], $id)); } $event['method'] = '__invoke'; @@ -126,10 +126,10 @@ class RegisterListenersPass implements CompilerPassInterface $class = $def->getClass(); if (!$r = $container->getReflectionClass($class)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); } if (!$r->isSubclassOf(EventSubscriberInterface::class)) { - throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EventSubscriberInterface::class)); + throw new InvalidArgumentException(\sprintf('Service "%s" must implement interface "%s".', $id, EventSubscriberInterface::class)); } $class = $r->name; @@ -181,7 +181,7 @@ class RegisterListenersPass implements CompilerPassInterface || $type->isBuiltin() || Event::class === ($name = $type->getName()) ) { - throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id)); + throw new InvalidArgumentException(\sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id)); } return $name; diff --git a/lib/symfony/event-dispatcher/EventDispatcher.php b/lib/symfony/event-dispatcher/EventDispatcher.php index 327803af6..605298926 100644 --- a/lib/symfony/event-dispatcher/EventDispatcher.php +++ b/lib/symfony/event-dispatcher/EventDispatcher.php @@ -42,7 +42,7 @@ class EventDispatcher implements EventDispatcherInterface } } - public function dispatch(object $event, string $eventName = null): object + public function dispatch(object $event, ?string $eventName = null): object { $eventName ??= $event::class; @@ -59,7 +59,7 @@ class EventDispatcher implements EventDispatcherInterface return $event; } - public function getListeners(string $eventName = null): array + public function getListeners(?string $eventName = null): array { if (null !== $eventName) { if (empty($this->listeners[$eventName])) { @@ -108,7 +108,7 @@ class EventDispatcher implements EventDispatcherInterface return null; } - public function hasListeners(string $eventName = null): bool + public function hasListeners(?string $eventName = null): bool { if (null !== $eventName) { return !empty($this->listeners[$eventName]); diff --git a/lib/symfony/event-dispatcher/EventDispatcherInterface.php b/lib/symfony/event-dispatcher/EventDispatcherInterface.php index 3cd94c938..e95a7b11d 100644 --- a/lib/symfony/event-dispatcher/EventDispatcherInterface.php +++ b/lib/symfony/event-dispatcher/EventDispatcherInterface.php @@ -59,7 +59,7 @@ interface EventDispatcherInterface extends ContractsEventDispatcherInterface * * @return array */ - public function getListeners(string $eventName = null): array; + public function getListeners(?string $eventName = null): array; /** * Gets the listener priority for a specific event. @@ -71,5 +71,5 @@ interface EventDispatcherInterface extends ContractsEventDispatcherInterface /** * Checks whether an event has any registered listeners. */ - public function hasListeners(string $eventName = null): bool; + public function hasListeners(?string $eventName = null): bool; } diff --git a/lib/symfony/event-dispatcher/GenericEvent.php b/lib/symfony/event-dispatcher/GenericEvent.php index 0ccbbd810..3bfeca045 100644 --- a/lib/symfony/event-dispatcher/GenericEvent.php +++ b/lib/symfony/event-dispatcher/GenericEvent.php @@ -59,7 +59,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate return $this->arguments[$key]; } - throw new \InvalidArgumentException(sprintf('Argument "%s" not found.', $key)); + throw new \InvalidArgumentException(\sprintf('Argument "%s" not found.', $key)); } /** diff --git a/lib/symfony/event-dispatcher/ImmutableEventDispatcher.php b/lib/symfony/event-dispatcher/ImmutableEventDispatcher.php index d385d3f83..301a805cb 100644 --- a/lib/symfony/event-dispatcher/ImmutableEventDispatcher.php +++ b/lib/symfony/event-dispatcher/ImmutableEventDispatcher.php @@ -25,7 +25,7 @@ class ImmutableEventDispatcher implements EventDispatcherInterface $this->dispatcher = $dispatcher; } - public function dispatch(object $event, string $eventName = null): object + public function dispatch(object $event, ?string $eventName = null): object { return $this->dispatcher->dispatch($event, $eventName); } @@ -62,7 +62,7 @@ class ImmutableEventDispatcher implements EventDispatcherInterface throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); } - public function getListeners(string $eventName = null): array + public function getListeners(?string $eventName = null): array { return $this->dispatcher->getListeners($eventName); } @@ -72,7 +72,7 @@ class ImmutableEventDispatcher implements EventDispatcherInterface return $this->dispatcher->getListenerPriority($eventName, $listener); } - public function hasListeners(string $eventName = null): bool + public function hasListeners(?string $eventName = null): bool { return $this->dispatcher->hasListeners($eventName); } diff --git a/lib/symfony/mailer/CHANGELOG.md b/lib/symfony/mailer/CHANGELOG.md new file mode 100644 index 000000000..6ef846cc8 --- /dev/null +++ b/lib/symfony/mailer/CHANGELOG.md @@ -0,0 +1,98 @@ +CHANGELOG +========= + +6.4 +--- + + * Add DSN parameter `peer_fingerprint` to verify TLS certificate fingerprint + * Change the default port for the `mailjet+smtp` transport from 465 to 587 + +6.3 +--- + + * Add `MessageEvent::reject()` to allow rejecting an email before sending it + * Change the default port for the `mailgun+smtp` transport from 465 to 587 + * Add `$authenticators` parameter in `EsmtpTransport` constructor and `EsmtpTransport::setAuthenticators()` + to allow overriding of default eSMTP authenticators + +6.2.7 +----- + + * [BC BREAK] The following data providers for `TransportFactoryTestCase` are now static: + `supportsProvider()`, `createProvider()`, `unsupportedSchemeProvider()`and `incompleteDsnProvider()` + +6.2 +--- + + * Add a `mailer:test` command + * Add `SentMessageEvent` and `FailedMessageEvent` events + +6.1 +--- + + * Make `start()` and `stop()` methods public on `SmtpTransport` + * Improve extensibility of `EsmtpTransport` + +6.0 +--- + + * The `HttpTransportException` class takes a string at first argument + +5.4 +--- + + * Enable the mailer to operate on any PSR-14-compatible event dispatcher + +5.3 +--- + + * added the `mailer` monolog channel and set it on all transport definitions + +5.2.0 +----- + + * added `NativeTransportFactory` to configure a transport based on php.ini settings + * added `local_domain`, `restart_threshold`, `restart_threshold_sleep` and `ping_threshold` options for `smtp` + * added `command` option for `sendmail` + +4.4.0 +----- + + * [BC BREAK] changed the `NullTransport` DSN from `smtp://null` to `null://null` + * [BC BREAK] renamed `SmtpEnvelope` to `Envelope`, renamed `DelayedSmtpEnvelope` to + `DelayedEnvelope` + * [BC BREAK] changed the syntax for failover and roundrobin DSNs + + Before: + + dummy://a || dummy://b (for failover) + dummy://a && dummy://b (for roundrobin) + + After: + + failover(dummy://a dummy://b) + roundrobin(dummy://a dummy://b) + + * added support for multiple transports on a `Mailer` instance + * [BC BREAK] removed the `auth_mode` DSN option (it is now always determined automatically) + * STARTTLS cannot be enabled anymore (it is used automatically if TLS is disabled and the server supports STARTTLS) + * [BC BREAK] Removed the `encryption` DSN option (use `smtps` instead) + * Added support for the `smtps` protocol (does the same as using `smtp` and port `465`) + * Added PHPUnit constraints + * Added `MessageDataCollector` + * Added `MessageEvents` and `MessageLoggerListener` to allow collecting sent emails + * [BC BREAK] `TransportInterface` has a new `__toString()` method + * [BC BREAK] Classes `AbstractApiTransport` and `AbstractHttpTransport` moved under `Transport` sub-namespace. + * [BC BREAK] Transports depend on `Symfony\Contracts\EventDispatcher\EventDispatcherInterface` + instead of `Symfony\Component\EventDispatcher\EventDispatcherInterface`. + * Added possibility to register custom transport for dsn by implementing + `Symfony\Component\Mailer\Transport\TransportFactoryInterface` and tagging with `mailer.transport_factory` tag in DI. + * Added `Symfony\Component\Mailer\Test\TransportFactoryTestCase` to ease testing custom transport factories. + * Added `SentMessage::getDebug()` and `TransportExceptionInterface::getDebug` to help debugging + * Made `MessageEvent` final + * add DSN parameter `verify_peer` to disable TLS peer verification for SMTP transport + +4.3.0 +----- + + * Added the component. diff --git a/lib/symfony/mailer/Command/MailerTestCommand.php b/lib/symfony/mailer/Command/MailerTestCommand.php new file mode 100644 index 000000000..8e00f6298 --- /dev/null +++ b/lib/symfony/mailer/Command/MailerTestCommand.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Command; + +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mime\Email; + +/** + * A console command to test Mailer transports. + */ +#[AsCommand(name: 'mailer:test', description: 'Test Mailer transports by sending an email')] +final class MailerTestCommand extends Command +{ + public function __construct(private TransportInterface $transport) + { + parent::__construct(); + } + + protected function configure(): void + { + $this + ->addArgument('to', InputArgument::REQUIRED, 'The recipient of the message') + ->addOption('from', null, InputOption::VALUE_REQUIRED, 'The sender of the message', 'from@example.org') + ->addOption('subject', null, InputOption::VALUE_REQUIRED, 'The subject of the message', 'Testing transport') + ->addOption('body', null, InputOption::VALUE_REQUIRED, 'The body of the message', 'Testing body') + ->addOption('transport', null, InputOption::VALUE_REQUIRED, 'The transport to be used') + ->setHelp(<<<'EOF' +The %command.name% command tests a Mailer transport by sending a simple email message: + +php %command.full_name% to@example.com + +You can also specify a specific transport: + + php %command.full_name% to@example.com --transport=transport_name + +Note that this command bypasses the Messenger bus if configured. + +EOF + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $message = (new Email()) + ->to($input->getArgument('to')) + ->from($input->getOption('from')) + ->subject($input->getOption('subject')) + ->text($input->getOption('body')) + ; + if ($transport = $input->getOption('transport')) { + $message->getHeaders()->addTextHeader('X-Transport', $transport); + } + + $this->transport->send($message); + + return 0; + } +} diff --git a/lib/symfony/mailer/DataCollector/MessageDataCollector.php b/lib/symfony/mailer/DataCollector/MessageDataCollector.php new file mode 100644 index 000000000..5c9ac3544 --- /dev/null +++ b/lib/symfony/mailer/DataCollector/MessageDataCollector.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\Mailer\Event\MessageEvents; +use Symfony\Component\Mailer\EventListener\MessageLoggerListener; + +/** + * @author Fabien Potencier + */ +final class MessageDataCollector extends DataCollector +{ + private MessageEvents $events; + + public function __construct(MessageLoggerListener $logger) + { + $this->events = $logger->getEvents(); + } + + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void + { + $this->data['events'] = $this->events; + } + + public function getEvents(): MessageEvents + { + return $this->data['events']; + } + + /** + * @internal + */ + public function base64Encode(string $data): string + { + return base64_encode($data); + } + + public function reset(): void + { + $this->data = []; + } + + public function getName(): string + { + return 'mailer'; + } +} diff --git a/lib/symfony/mailer/DelayedEnvelope.php b/lib/symfony/mailer/DelayedEnvelope.php new file mode 100644 index 000000000..7458db2f0 --- /dev/null +++ b/lib/symfony/mailer/DelayedEnvelope.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Header\Headers; +use Symfony\Component\Mime\Message; + +/** + * @author Fabien Potencier + * + * @internal + */ +final class DelayedEnvelope extends Envelope +{ + private bool $senderSet = false; + private bool $recipientsSet = false; + private Message $message; + + public function __construct(Message $message) + { + $this->message = $message; + } + + public function setSender(Address $sender): void + { + parent::setSender($sender); + + $this->senderSet = true; + } + + public function getSender(): Address + { + if (!$this->senderSet) { + parent::setSender(self::getSenderFromHeaders($this->message->getHeaders())); + } + + return parent::getSender(); + } + + public function setRecipients(array $recipients): void + { + parent::setRecipients($recipients); + + $this->recipientsSet = (bool) parent::getRecipients(); + } + + /** + * @return Address[] + */ + public function getRecipients(): array + { + if ($this->recipientsSet) { + return parent::getRecipients(); + } + + return self::getRecipientsFromHeaders($this->message->getHeaders()); + } + + private static function getRecipientsFromHeaders(Headers $headers): array + { + $recipients = []; + foreach (['to', 'cc', 'bcc'] as $name) { + foreach ($headers->all($name) as $header) { + foreach ($header->getAddresses() as $address) { + $recipients[] = $address; + } + } + } + + return $recipients; + } + + private static function getSenderFromHeaders(Headers $headers): Address + { + if ($sender = $headers->get('Sender')) { + return $sender->getAddress(); + } + if ($return = $headers->get('Return-Path')) { + return $return->getAddress(); + } + if ($from = $headers->get('From')) { + return $from->getAddresses()[0]; + } + + throw new LogicException('Unable to determine the sender of the message.'); + } +} diff --git a/lib/symfony/mailer/Envelope.php b/lib/symfony/mailer/Envelope.php new file mode 100644 index 000000000..45e1db363 --- /dev/null +++ b/lib/symfony/mailer/Envelope.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +class Envelope +{ + private Address $sender; + private array $recipients = []; + + /** + * @param Address[] $recipients + */ + public function __construct(Address $sender, array $recipients) + { + $this->setSender($sender); + $this->setRecipients($recipients); + } + + public static function create(RawMessage $message): self + { + if (RawMessage::class === $message::class) { + throw new LogicException('Cannot send a RawMessage instance without an explicit Envelope.'); + } + + return new DelayedEnvelope($message); + } + + public function setSender(Address $sender): void + { + // to ensure deliverability of bounce emails independent of UTF-8 capabilities of SMTP servers + if (!preg_match('/^[^@\x80-\xFF]++@/', $sender->getAddress())) { + throw new InvalidArgumentException(\sprintf('Invalid sender "%s": non-ASCII characters not supported in local-part of email.', $sender->getAddress())); + } + $this->sender = $sender; + } + + /** + * @return Address Returns a "mailbox" as specified by RFC 2822 + * Must be converted to an "addr-spec" when used as a "MAIL FROM" value in SMTP (use getAddress()) + */ + public function getSender(): Address + { + return $this->sender; + } + + /** + * @param Address[] $recipients + */ + public function setRecipients(array $recipients): void + { + if (!$recipients) { + throw new InvalidArgumentException('An envelope must have at least one recipient.'); + } + + $this->recipients = []; + foreach ($recipients as $recipient) { + if (!$recipient instanceof Address) { + throw new InvalidArgumentException(\sprintf('A recipient must be an instance of "%s" (got "%s").', Address::class, get_debug_type($recipient))); + } + $this->recipients[] = new Address($recipient->getAddress()); + } + } + + /** + * @return Address[] + */ + public function getRecipients(): array + { + return $this->recipients; + } +} diff --git a/lib/symfony/mailer/Event/FailedMessageEvent.php b/lib/symfony/mailer/Event/FailedMessageEvent.php new file mode 100644 index 000000000..4808c659d --- /dev/null +++ b/lib/symfony/mailer/Event/FailedMessageEvent.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mime\RawMessage; +use Symfony\Contracts\EventDispatcher\Event; + +/** + * @author Fabien Potencier + */ +final class FailedMessageEvent extends Event +{ + public function __construct( + private RawMessage $message, + private \Throwable $error, + ) { + } + + public function getMessage(): RawMessage + { + return $this->message; + } + + public function getError(): \Throwable + { + return $this->error; + } +} diff --git a/lib/symfony/mailer/Event/MessageEvent.php b/lib/symfony/mailer/Event/MessageEvent.php new file mode 100644 index 000000000..7f466451a --- /dev/null +++ b/lib/symfony/mailer/Event/MessageEvent.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Messenger\Stamp\StampInterface; +use Symfony\Component\Mime\RawMessage; +use Symfony\Contracts\EventDispatcher\Event; + +/** + * Allows the transformation of a Message and the Envelope before the email is sent. + * + * @author Fabien Potencier + */ +final class MessageEvent extends Event +{ + private RawMessage $message; + private Envelope $envelope; + private string $transport; + private bool $queued; + private bool $rejected = false; + + /** @var StampInterface[] */ + private array $stamps = []; + + public function __construct(RawMessage $message, Envelope $envelope, string $transport, bool $queued = false) + { + $this->message = $message; + $this->envelope = $envelope; + $this->transport = $transport; + $this->queued = $queued; + } + + public function getMessage(): RawMessage + { + return $this->message; + } + + public function setMessage(RawMessage $message): void + { + $this->message = $message; + } + + public function getEnvelope(): Envelope + { + return $this->envelope; + } + + public function setEnvelope(Envelope $envelope): void + { + $this->envelope = $envelope; + } + + public function getTransport(): string + { + return $this->transport; + } + + public function isQueued(): bool + { + return $this->queued; + } + + public function isRejected(): bool + { + return $this->rejected; + } + + public function reject(): void + { + $this->rejected = true; + $this->stopPropagation(); + } + + public function addStamp(StampInterface $stamp): void + { + if (!$this->queued) { + throw new LogicException(\sprintf('Cannot call "%s()" on a message that is not meant to be queued.', __METHOD__)); + } + + $this->stamps[] = $stamp; + } + + /** + * @return StampInterface[] + */ + public function getStamps(): array + { + if (!$this->queued) { + throw new LogicException(\sprintf('Cannot call "%s()" on a message that is not meant to be queued.', __METHOD__)); + } + + return $this->stamps; + } +} diff --git a/lib/symfony/mailer/Event/MessageEvents.php b/lib/symfony/mailer/Event/MessageEvents.php new file mode 100644 index 000000000..2b438e382 --- /dev/null +++ b/lib/symfony/mailer/Event/MessageEvents.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +class MessageEvents +{ + /** + * @var MessageEvent[] + */ + private array $events = []; + + /** + * @var array + */ + private array $transports = []; + + public function add(MessageEvent $event): void + { + $this->events[] = $event; + $this->transports[$event->getTransport()] = true; + } + + public function getTransports(): array + { + return array_keys($this->transports); + } + + /** + * @return MessageEvent[] + */ + public function getEvents(?string $name = null): array + { + if (null === $name) { + return $this->events; + } + + $events = []; + foreach ($this->events as $event) { + if ($name === $event->getTransport()) { + $events[] = $event; + } + } + + return $events; + } + + /** + * @return RawMessage[] + */ + public function getMessages(?string $name = null): array + { + $events = $this->getEvents($name); + $messages = []; + foreach ($events as $event) { + $messages[] = $event->getMessage(); + } + + return $messages; + } +} diff --git a/lib/symfony/mailer/Event/SentMessageEvent.php b/lib/symfony/mailer/Event/SentMessageEvent.php new file mode 100644 index 000000000..a412a9f46 --- /dev/null +++ b/lib/symfony/mailer/Event/SentMessageEvent.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mailer\SentMessage; +use Symfony\Contracts\EventDispatcher\Event; + +/** + * @author Fabien Potencier + */ +final class SentMessageEvent extends Event +{ + public function __construct(private SentMessage $message) + { + } + + public function getMessage(): SentMessage + { + return $this->message; + } +} diff --git a/lib/symfony/mailer/EventListener/EnvelopeListener.php b/lib/symfony/mailer/EventListener/EnvelopeListener.php new file mode 100644 index 000000000..db9dd723a --- /dev/null +++ b/lib/symfony/mailer/EventListener/EnvelopeListener.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Message; + +/** + * Manipulates the Envelope of a Message. + * + * @author Fabien Potencier + */ +class EnvelopeListener implements EventSubscriberInterface +{ + private ?Address $sender = null; + + /** + * @var Address[]|null + */ + private ?array $recipients = null; + + /** + * @param array $recipients + */ + public function __construct(Address|string|null $sender = null, ?array $recipients = null) + { + if (null !== $sender) { + $this->sender = Address::create($sender); + } + if (null !== $recipients) { + $this->recipients = Address::createArray($recipients); + } + } + + public function onMessage(MessageEvent $event): void + { + if ($this->sender) { + $event->getEnvelope()->setSender($this->sender); + + $message = $event->getMessage(); + if ($message instanceof Message) { + if (!$message->getHeaders()->has('Sender') && !$message->getHeaders()->has('From')) { + $message->getHeaders()->addMailboxHeader('Sender', $this->sender); + } + } + } + + if ($this->recipients) { + $event->getEnvelope()->setRecipients($this->recipients); + } + } + + public static function getSubscribedEvents(): array + { + return [ + // should be the last one to allow header changes by other listeners first + MessageEvent::class => ['onMessage', -255], + ]; + } +} diff --git a/lib/symfony/mailer/EventListener/MessageListener.php b/lib/symfony/mailer/EventListener/MessageListener.php new file mode 100644 index 000000000..2d370b7e9 --- /dev/null +++ b/lib/symfony/mailer/EventListener/MessageListener.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\RuntimeException; +use Symfony\Component\Mime\BodyRendererInterface; +use Symfony\Component\Mime\Header\Headers; +use Symfony\Component\Mime\Header\MailboxListHeader; +use Symfony\Component\Mime\Message; + +/** + * Manipulates the headers and the body of a Message. + * + * @author Fabien Potencier + */ +class MessageListener implements EventSubscriberInterface +{ + public const HEADER_SET_IF_EMPTY = 1; + public const HEADER_ADD = 2; + public const HEADER_REPLACE = 3; + public const DEFAULT_RULES = [ + 'from' => self::HEADER_SET_IF_EMPTY, + 'return-path' => self::HEADER_SET_IF_EMPTY, + 'reply-to' => self::HEADER_ADD, + 'to' => self::HEADER_SET_IF_EMPTY, + 'cc' => self::HEADER_ADD, + 'bcc' => self::HEADER_ADD, + ]; + + private ?Headers $headers; + private array $headerRules = []; + private ?BodyRendererInterface $renderer; + + public function __construct(?Headers $headers = null, ?BodyRendererInterface $renderer = null, array $headerRules = self::DEFAULT_RULES) + { + $this->headers = $headers; + $this->renderer = $renderer; + foreach ($headerRules as $headerName => $rule) { + $this->addHeaderRule($headerName, $rule); + } + } + + public function addHeaderRule(string $headerName, int $rule): void + { + if ($rule < 1 || $rule > 3) { + throw new InvalidArgumentException(\sprintf('The "%d" rule is not supported.', $rule)); + } + + $this->headerRules[strtolower($headerName)] = $rule; + } + + public function onMessage(MessageEvent $event): void + { + $message = $event->getMessage(); + if (!$message instanceof Message) { + return; + } + + $this->setHeaders($message); + $this->renderMessage($message); + } + + private function setHeaders(Message $message): void + { + if (!$this->headers) { + return; + } + + $headers = $message->getHeaders(); + foreach ($this->headers->all() as $name => $header) { + if (!$headers->has($name)) { + $headers->add($header); + + continue; + } + + switch ($this->headerRules[$name] ?? self::HEADER_SET_IF_EMPTY) { + case self::HEADER_SET_IF_EMPTY: + break; + + case self::HEADER_REPLACE: + $headers->remove($name); + $headers->add($header); + + break; + + case self::HEADER_ADD: + if (!Headers::isUniqueHeader($name)) { + $headers->add($header); + + break; + } + + $h = $headers->get($name); + if (!$h instanceof MailboxListHeader) { + throw new RuntimeException(\sprintf('Unable to set header "%s".', $name)); + } + + Headers::checkHeaderClass($header); + foreach ($header->getAddresses() as $address) { + $h->addAddress($address); + } + } + } + } + + private function renderMessage(Message $message): void + { + if (!$this->renderer) { + return; + } + + $this->renderer->render($message); + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => 'onMessage', + ]; + } +} diff --git a/lib/symfony/mailer/EventListener/MessageLoggerListener.php b/lib/symfony/mailer/EventListener/MessageLoggerListener.php new file mode 100644 index 000000000..6c5605fa8 --- /dev/null +++ b/lib/symfony/mailer/EventListener/MessageLoggerListener.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Event\MessageEvents; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Logs Messages. + * + * @author Fabien Potencier + */ +class MessageLoggerListener implements EventSubscriberInterface, ResetInterface +{ + private MessageEvents $events; + + public function __construct() + { + $this->events = new MessageEvents(); + } + + /** + * @return void + */ + public function reset() + { + $this->events = new MessageEvents(); + } + + public function onMessage(MessageEvent $event): void + { + $this->events->add($event); + } + + public function getEvents(): MessageEvents + { + return $this->events; + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => ['onMessage', -255], + ]; + } +} diff --git a/lib/symfony/mailer/EventListener/MessengerTransportListener.php b/lib/symfony/mailer/EventListener/MessengerTransportListener.php new file mode 100644 index 000000000..8cf8cc800 --- /dev/null +++ b/lib/symfony/mailer/EventListener/MessengerTransportListener.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\EventListener; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Messenger\Stamp\TransportNamesStamp; +use Symfony\Component\Mime\Message; + +/** + * Allows messages to be sent to specific Messenger transports via the "X-Bus-Transport" MIME header. + * + * @author Fabien Potencier + */ +final class MessengerTransportListener implements EventSubscriberInterface +{ + public function onMessage(MessageEvent $event): void + { + if (!$event->isQueued()) { + return; + } + + $message = $event->getMessage(); + if (!$message instanceof Message || !$message->getHeaders()->has('X-Bus-Transport')) { + return; + } + + $names = $message->getHeaders()->get('X-Bus-Transport')->getBody(); + $names = array_map('trim', explode(',', $names)); + $event->addStamp(new TransportNamesStamp($names)); + $message->getHeaders()->remove('X-Bus-Transport'); + } + + public static function getSubscribedEvents(): array + { + return [ + MessageEvent::class => 'onMessage', + ]; + } +} diff --git a/lib/symfony/mailer/Exception/ExceptionInterface.php b/lib/symfony/mailer/Exception/ExceptionInterface.php new file mode 100644 index 000000000..2f0f3a6f9 --- /dev/null +++ b/lib/symfony/mailer/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Fabien Potencier + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/lib/symfony/mailer/Exception/HttpTransportException.php b/lib/symfony/mailer/Exception/HttpTransportException.php new file mode 100644 index 000000000..ad10910f3 --- /dev/null +++ b/lib/symfony/mailer/Exception/HttpTransportException.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Fabien Potencier + */ +class HttpTransportException extends TransportException +{ + private ResponseInterface $response; + + public function __construct(string $message, ResponseInterface $response, int $code = 0, ?\Throwable $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->response = $response; + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } +} diff --git a/lib/symfony/mailer/Exception/IncompleteDsnException.php b/lib/symfony/mailer/Exception/IncompleteDsnException.php new file mode 100644 index 000000000..f2618b65d --- /dev/null +++ b/lib/symfony/mailer/Exception/IncompleteDsnException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Konstantin Myakshin + */ +class IncompleteDsnException extends InvalidArgumentException +{ +} diff --git a/lib/symfony/mailer/Exception/InvalidArgumentException.php b/lib/symfony/mailer/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..ba5333456 --- /dev/null +++ b/lib/symfony/mailer/Exception/InvalidArgumentException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/lib/symfony/mailer/Exception/LogicException.php b/lib/symfony/mailer/Exception/LogicException.php new file mode 100644 index 000000000..487c0a34f --- /dev/null +++ b/lib/symfony/mailer/Exception/LogicException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/lib/symfony/mailer/Exception/RuntimeException.php b/lib/symfony/mailer/Exception/RuntimeException.php new file mode 100644 index 000000000..44b79cc64 --- /dev/null +++ b/lib/symfony/mailer/Exception/RuntimeException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/lib/symfony/mailer/Exception/TransportException.php b/lib/symfony/mailer/Exception/TransportException.php new file mode 100644 index 000000000..ea538d6fa --- /dev/null +++ b/lib/symfony/mailer/Exception/TransportException.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +class TransportException extends RuntimeException implements TransportExceptionInterface +{ + private string $debug = ''; + + public function getDebug(): string + { + return $this->debug; + } + + public function appendDebug(string $debug): void + { + $this->debug .= $debug; + } +} diff --git a/lib/symfony/mailer/Exception/TransportExceptionInterface.php b/lib/symfony/mailer/Exception/TransportExceptionInterface.php new file mode 100644 index 000000000..4318f5ce1 --- /dev/null +++ b/lib/symfony/mailer/Exception/TransportExceptionInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +/** + * @author Fabien Potencier + */ +interface TransportExceptionInterface extends ExceptionInterface +{ + public function getDebug(): string; + + public function appendDebug(string $debug): void; +} diff --git a/lib/symfony/mailer/Exception/UnexpectedResponseException.php b/lib/symfony/mailer/Exception/UnexpectedResponseException.php new file mode 100644 index 000000000..e779df122 --- /dev/null +++ b/lib/symfony/mailer/Exception/UnexpectedResponseException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +class UnexpectedResponseException extends TransportException +{ +} diff --git a/lib/symfony/mailer/Exception/UnsupportedSchemeException.php b/lib/symfony/mailer/Exception/UnsupportedSchemeException.php new file mode 100644 index 000000000..eacad1010 --- /dev/null +++ b/lib/symfony/mailer/Exception/UnsupportedSchemeException.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Exception; + +use Symfony\Component\Mailer\Bridge; +use Symfony\Component\Mailer\Transport\Dsn; + +/** + * @author Konstantin Myakshin + */ +class UnsupportedSchemeException extends LogicException +{ + private const SCHEME_TO_PACKAGE_MAP = [ + 'brevo' => [ + 'class' => Bridge\Brevo\Transport\BrevoTransportFactory::class, + 'package' => 'symfony/brevo-mailer', + ], + 'gmail' => [ + 'class' => Bridge\Google\Transport\GmailTransportFactory::class, + 'package' => 'symfony/google-mailer', + ], + 'infobip' => [ + 'class' => Bridge\Infobip\Transport\InfobipTransportFactory::class, + 'package' => 'symfony/infobip-mailer', + ], + 'mailersend' => [ + 'class' => Bridge\MailerSend\Transport\MailerSendTransportFactory::class, + 'package' => 'symfony/mailersend-mailer', + ], + 'mailgun' => [ + 'class' => Bridge\Mailgun\Transport\MailgunTransportFactory::class, + 'package' => 'symfony/mailgun-mailer', + ], + 'mailjet' => [ + 'class' => Bridge\Mailjet\Transport\MailjetTransportFactory::class, + 'package' => 'symfony/mailjet-mailer', + ], + 'mailpace' => [ + 'class' => Bridge\MailPace\Transport\MailPaceTransportFactory::class, + 'package' => 'symfony/mail-pace-mailer', + ], + 'mandrill' => [ + 'class' => Bridge\Mailchimp\Transport\MandrillTransportFactory::class, + 'package' => 'symfony/mailchimp-mailer', + ], + 'ohmysmtp' => [ + 'class' => Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory::class, + 'package' => 'symfony/oh-my-smtp-mailer', + ], + 'postmark' => [ + 'class' => Bridge\Postmark\Transport\PostmarkTransportFactory::class, + 'package' => 'symfony/postmark-mailer', + ], + 'scaleway' => [ + 'class' => Bridge\Scaleway\Transport\ScalewayTransportFactory::class, + 'package' => 'symfony/scaleway-mailer', + ], + 'sendgrid' => [ + 'class' => Bridge\Sendgrid\Transport\SendgridTransportFactory::class, + 'package' => 'symfony/sendgrid-mailer', + ], + 'sendinblue' => [ + 'class' => Bridge\Sendinblue\Transport\SendinblueTransportFactory::class, + 'package' => 'symfony/sendinblue-mailer', + ], + 'ses' => [ + 'class' => Bridge\Amazon\Transport\SesTransportFactory::class, + 'package' => 'symfony/amazon-mailer', + ], + ]; + + public function __construct(Dsn $dsn, ?string $name = null, array $supported = []) + { + $provider = $dsn->getScheme(); + if (false !== $pos = strpos($provider, '+')) { + $provider = substr($provider, 0, $pos); + } + $package = self::SCHEME_TO_PACKAGE_MAP[$provider] ?? null; + if ($package && !class_exists($package['class'])) { + parent::__construct(\sprintf('Unable to send emails via "%s" as the bridge is not installed. Try running "composer require %s".', $provider, $package['package'])); + + return; + } + + $message = \sprintf('The "%s" scheme is not supported', $dsn->getScheme()); + if ($name && $supported) { + $message .= \sprintf('; supported schemes for mailer "%s" are: "%s"', $name, implode('", "', $supported)); + } + + parent::__construct($message.'.'); + } +} diff --git a/lib/symfony/mailer/Header/MetadataHeader.php b/lib/symfony/mailer/Header/MetadataHeader.php new file mode 100644 index 000000000..d6ee5440d --- /dev/null +++ b/lib/symfony/mailer/Header/MetadataHeader.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Header; + +use Symfony\Component\Mime\Header\UnstructuredHeader; + +/** + * @author Kevin Bond + */ +final class MetadataHeader extends UnstructuredHeader +{ + private string $key; + + public function __construct(string $key, string $value) + { + $this->key = $key; + + parent::__construct('X-Metadata-'.$key, $value); + } + + public function getKey(): string + { + return $this->key; + } +} diff --git a/lib/symfony/mailer/Header/TagHeader.php b/lib/symfony/mailer/Header/TagHeader.php new file mode 100644 index 000000000..7115caebe --- /dev/null +++ b/lib/symfony/mailer/Header/TagHeader.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Header; + +use Symfony\Component\Mime\Header\UnstructuredHeader; + +/** + * @author Kevin Bond + */ +final class TagHeader extends UnstructuredHeader +{ + public function __construct(string $value) + { + parent::__construct('X-Tag', $value); + } +} diff --git a/lib/symfony/polyfill-php72/LICENSE b/lib/symfony/mailer/LICENSE similarity index 95% rename from lib/symfony/polyfill-php72/LICENSE rename to lib/symfony/mailer/LICENSE index 6e3afce69..f37c76b59 100644 --- a/lib/symfony/polyfill-php72/LICENSE +++ b/lib/symfony/mailer/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-present Fabien Potencier +Copyright (c) 2019-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/symfony/mailer/Mailer.php b/lib/symfony/mailer/Mailer.php new file mode 100644 index 000000000..6df99091a --- /dev/null +++ b/lib/symfony/mailer/Mailer.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Messenger\SendEmailMessage; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Messenger\Exception\HandlerFailedException; +use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +final class Mailer implements MailerInterface +{ + private TransportInterface $transport; + private ?MessageBusInterface $bus; + private ?EventDispatcherInterface $dispatcher; + + public function __construct(TransportInterface $transport, ?MessageBusInterface $bus = null, ?EventDispatcherInterface $dispatcher = null) + { + $this->transport = $transport; + $this->bus = $bus; + $this->dispatcher = $dispatcher; + } + + public function send(RawMessage $message, ?Envelope $envelope = null): void + { + if (null === $this->bus) { + $this->transport->send($message, $envelope); + + return; + } + + $stamps = []; + if (null !== $this->dispatcher) { + // The dispatched event here has `queued` set to `true`; the goal is NOT to render the message, but to let + // listeners do something before a message is sent to the queue. + // We are using a cloned message as we still want to dispatch the **original** message, not the one modified by listeners. + // That's because the listeners will run again when the email is sent via Messenger by the transport (see `AbstractTransport`). + // Listeners should act depending on the `$queued` argument of the `MessageEvent` instance. + $clonedMessage = clone $message; + $clonedEnvelope = null !== $envelope ? clone $envelope : Envelope::create($clonedMessage); + $event = new MessageEvent($clonedMessage, $clonedEnvelope, (string) $this->transport, true); + $this->dispatcher->dispatch($event); + $stamps = $event->getStamps(); + + if ($event->isRejected()) { + return; + } + } + + try { + $this->bus->dispatch(new SendEmailMessage($message, $envelope), $stamps); + } catch (HandlerFailedException $e) { + foreach ($e->getWrappedExceptions() as $nested) { + if ($nested instanceof TransportExceptionInterface) { + throw $nested; + } + } + throw $e; + } + } +} diff --git a/lib/symfony/mailer/MailerInterface.php b/lib/symfony/mailer/MailerInterface.php new file mode 100644 index 000000000..ebac4b53e --- /dev/null +++ b/lib/symfony/mailer/MailerInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mime\RawMessage; + +/** + * Interface for mailers able to send emails synchronously and/or asynchronously. + * + * Implementations must support synchronous and asynchronous sending. + * + * @author Fabien Potencier + */ +interface MailerInterface +{ + /** + * @throws TransportExceptionInterface + */ + public function send(RawMessage $message, ?Envelope $envelope = null): void; +} diff --git a/lib/symfony/mailer/Messenger/MessageHandler.php b/lib/symfony/mailer/Messenger/MessageHandler.php new file mode 100644 index 000000000..f8fb14fce --- /dev/null +++ b/lib/symfony/mailer/Messenger/MessageHandler.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Messenger; + +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mailer\Transport\TransportInterface; + +/** + * @author Fabien Potencier + */ +class MessageHandler +{ + private TransportInterface $transport; + + public function __construct(TransportInterface $transport) + { + $this->transport = $transport; + } + + public function __invoke(SendEmailMessage $message): ?SentMessage + { + return $this->transport->send($message->getMessage(), $message->getEnvelope()); + } +} diff --git a/lib/symfony/mailer/Messenger/SendEmailMessage.php b/lib/symfony/mailer/Messenger/SendEmailMessage.php new file mode 100644 index 000000000..18bd50620 --- /dev/null +++ b/lib/symfony/mailer/Messenger/SendEmailMessage.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Messenger; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +class SendEmailMessage +{ + private RawMessage $message; + private ?Envelope $envelope; + + public function __construct(RawMessage $message, ?Envelope $envelope = null) + { + $this->message = $message; + $this->envelope = $envelope; + } + + public function getMessage(): RawMessage + { + return $this->message; + } + + public function getEnvelope(): ?Envelope + { + return $this->envelope; + } +} diff --git a/lib/symfony/mailer/README.md b/lib/symfony/mailer/README.md new file mode 100644 index 000000000..43e7dfe05 --- /dev/null +++ b/lib/symfony/mailer/README.md @@ -0,0 +1,74 @@ +Mailer Component +================ + +The Mailer component helps sending emails. + +Getting Started +--------------- + +``` +$ composer require symfony/mailer +``` + +```php +use Symfony\Component\Mailer\Transport; +use Symfony\Component\Mailer\Mailer; +use Symfony\Component\Mime\Email; + +$transport = Transport::fromDsn('smtp://localhost'); +$mailer = new Mailer($transport); + +$email = (new Email()) + ->from('hello@example.com') + ->to('you@example.com') + //->cc('cc@example.com') + //->bcc('bcc@example.com') + //->replyTo('fabien@example.com') + //->priority(Email::PRIORITY_HIGH) + ->subject('Time for Symfony Mailer!') + ->text('Sending emails is fun again!') + ->html('

See Twig integration for better HTML integration!

'); + +$mailer->send($email); +``` + +To enable the Twig integration of the Mailer, require `symfony/twig-bridge` and +set up the `BodyRenderer`: + +```php +use Symfony\Bridge\Twig\Mime\BodyRenderer; +use Symfony\Bridge\Twig\Mime\TemplatedEmail; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Mailer\EventListener\MessageListener; +use Symfony\Component\Mailer\Mailer; +use Symfony\Component\Mailer\Transport; +use Twig\Environment as TwigEnvironment; + +$twig = new TwigEnvironment(...); +$messageListener = new MessageListener(null, new BodyRenderer($twig)); + +$eventDispatcher = new EventDispatcher(); +$eventDispatcher->addSubscriber($messageListener); + +$transport = Transport::fromDsn('smtp://localhost', $eventDispatcher); +$mailer = new Mailer($transport, null, $eventDispatcher); + +$email = (new TemplatedEmail()) + // ... + ->htmlTemplate('emails/signup.html.twig') + ->context([ + 'expiration_date' => new \DateTimeImmutable('+7 days'), + 'username' => 'foo', + ]) +; +$mailer->send($email); +``` + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/mailer.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/lib/symfony/mailer/SentMessage.php b/lib/symfony/mailer/SentMessage.php new file mode 100644 index 000000000..be8471180 --- /dev/null +++ b/lib/symfony/mailer/SentMessage.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +class SentMessage +{ + private RawMessage $original; + private RawMessage $raw; + private Envelope $envelope; + private string $messageId; + private string $debug = ''; + + /** + * @internal + */ + public function __construct(RawMessage $message, Envelope $envelope) + { + $message->ensureValidity(); + + $this->original = $message; + $this->envelope = $envelope; + + if ($message instanceof Message) { + $message = clone $message; + $headers = $message->getHeaders(); + if (!$headers->has('Message-ID')) { + $headers->addIdHeader('Message-ID', $message->generateMessageId()); + } + $this->messageId = $headers->get('Message-ID')->getId(); + $this->raw = new RawMessage($message->toIterable()); + } else { + $this->raw = $message; + } + } + + public function getMessage(): RawMessage + { + return $this->raw; + } + + public function getOriginalMessage(): RawMessage + { + return $this->original; + } + + public function getEnvelope(): Envelope + { + return $this->envelope; + } + + public function setMessageId(string $id): void + { + $this->messageId = $id; + } + + public function getMessageId(): string + { + return $this->messageId; + } + + public function getDebug(): string + { + return $this->debug; + } + + public function appendDebug(string $debug): void + { + $this->debug .= $debug; + } + + public function toString(): string + { + return $this->raw->toString(); + } + + public function toIterable(): iterable + { + return $this->raw->toIterable(); + } +} diff --git a/lib/symfony/mailer/Test/Constraint/EmailCount.php b/lib/symfony/mailer/Test/Constraint/EmailCount.php new file mode 100644 index 000000000..47a4e621e --- /dev/null +++ b/lib/symfony/mailer/Test/Constraint/EmailCount.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mailer\Event\MessageEvents; + +final class EmailCount extends Constraint +{ + private int $expectedValue; + private ?string $transport; + private bool $queued; + + public function __construct(int $expectedValue, ?string $transport = null, bool $queued = false) + { + $this->expectedValue = $expectedValue; + $this->transport = $transport; + $this->queued = $queued; + } + + public function toString(): string + { + return \sprintf('%shas %s "%d" emails', $this->transport ? $this->transport.' ' : '', $this->queued ? 'queued' : 'sent', $this->expectedValue); + } + + /** + * @param MessageEvents $events + */ + protected function matches($events): bool + { + return $this->expectedValue === $this->countEmails($events); + } + + /** + * @param MessageEvents $events + */ + protected function failureDescription($events): string + { + return \sprintf('the Transport %s (%d %s)', $this->toString(), $this->countEmails($events), $this->queued ? 'queued' : 'sent'); + } + + private function countEmails(MessageEvents $events): int + { + $count = 0; + foreach ($events->getEvents($this->transport) as $event) { + if ( + ($this->queued && $event->isQueued()) + || (!$this->queued && !$event->isQueued()) + ) { + ++$count; + } + } + + return $count; + } +} diff --git a/lib/symfony/mailer/Test/Constraint/EmailIsQueued.php b/lib/symfony/mailer/Test/Constraint/EmailIsQueued.php new file mode 100644 index 000000000..46436aa06 --- /dev/null +++ b/lib/symfony/mailer/Test/Constraint/EmailIsQueued.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\Mailer\Event\MessageEvent; + +final class EmailIsQueued extends Constraint +{ + public function toString(): string + { + return 'is queued'; + } + + /** + * @param MessageEvent $event + */ + protected function matches($event): bool + { + return $event->isQueued(); + } + + /** + * @param MessageEvent $event + */ + protected function failureDescription($event): string + { + return 'the Email '.$this->toString(); + } +} diff --git a/lib/symfony/mailer/Test/TransportFactoryTestCase.php b/lib/symfony/mailer/Test/TransportFactoryTestCase.php new file mode 100644 index 000000000..5156086ae --- /dev/null +++ b/lib/symfony/mailer/Test/TransportFactoryTestCase.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Test; + +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Exception\IncompleteDsnException; +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; +use Symfony\Component\Mailer\Transport\Dsn; +use Symfony\Component\Mailer\Transport\TransportFactoryInterface; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * A test case to ease testing Transport Factory. + * + * @author Konstantin Myakshin + */ +abstract class TransportFactoryTestCase extends TestCase +{ + protected const USER = 'u$er'; + protected const PASSWORD = 'pa$s'; + + protected $dispatcher; + protected $client; + protected $logger; + + abstract public function getFactory(): TransportFactoryInterface; + + abstract public static function supportsProvider(): iterable; + + abstract public static function createProvider(): iterable; + + public static function unsupportedSchemeProvider(): iterable + { + return []; + } + + public static function incompleteDsnProvider(): iterable + { + return []; + } + + /** + * @dataProvider supportsProvider + */ + public function testSupports(Dsn $dsn, bool $supports) + { + $factory = $this->getFactory(); + + $this->assertSame($supports, $factory->supports($dsn)); + } + + /** + * @dataProvider createProvider + */ + public function testCreate(Dsn $dsn, TransportInterface $transport) + { + $factory = $this->getFactory(); + + $this->assertEquals($transport, $factory->create($dsn)); + if (str_contains('smtp', $dsn->getScheme())) { + $this->assertStringMatchesFormat($dsn->getScheme().'://%S'.$dsn->getHost().'%S', (string) $transport); + } + } + + /** + * @dataProvider unsupportedSchemeProvider + */ + public function testUnsupportedSchemeException(Dsn $dsn, ?string $message = null) + { + $factory = $this->getFactory(); + + $this->expectException(UnsupportedSchemeException::class); + if (null !== $message) { + $this->expectExceptionMessage($message); + } + + $factory->create($dsn); + } + + /** + * @dataProvider incompleteDsnProvider + */ + public function testIncompleteDsnException(Dsn $dsn) + { + $factory = $this->getFactory(); + + $this->expectException(IncompleteDsnException::class); + $factory->create($dsn); + } + + protected function getDispatcher(): EventDispatcherInterface + { + return $this->dispatcher ??= $this->createMock(EventDispatcherInterface::class); + } + + protected function getClient(): HttpClientInterface + { + return $this->client ??= $this->createMock(HttpClientInterface::class); + } + + protected function getLogger(): LoggerInterface + { + return $this->logger ??= $this->createMock(LoggerInterface::class); + } +} diff --git a/lib/symfony/mailer/Transport.php b/lib/symfony/mailer/Transport.php new file mode 100644 index 000000000..945b70db0 --- /dev/null +++ b/lib/symfony/mailer/Transport.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Bridge\Amazon\Transport\SesTransportFactory; +use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoTransportFactory; +use Symfony\Component\Mailer\Bridge\Google\Transport\GmailTransportFactory; +use Symfony\Component\Mailer\Bridge\Infobip\Transport\InfobipTransportFactory; +use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillTransportFactory; +use Symfony\Component\Mailer\Bridge\MailerSend\Transport\MailerSendTransportFactory; +use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory; +use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetTransportFactory; +use Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceTransportFactory; +use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory; +use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory; +use Symfony\Component\Mailer\Bridge\Scaleway\Transport\ScalewayTransportFactory; +use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory; +use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory; +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; +use Symfony\Component\Mailer\Transport\Dsn; +use Symfony\Component\Mailer\Transport\FailoverTransport; +use Symfony\Component\Mailer\Transport\NativeTransportFactory; +use Symfony\Component\Mailer\Transport\NullTransportFactory; +use Symfony\Component\Mailer\Transport\RoundRobinTransport; +use Symfony\Component\Mailer\Transport\SendmailTransportFactory; +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory; +use Symfony\Component\Mailer\Transport\TransportFactoryInterface; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mailer\Transport\Transports; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * @author Fabien Potencier + * @author Konstantin Myakshin + */ +final class Transport +{ + private const FACTORY_CLASSES = [ + BrevoTransportFactory::class, + GmailTransportFactory::class, + InfobipTransportFactory::class, + MailerSendTransportFactory::class, + MailgunTransportFactory::class, + MailjetTransportFactory::class, + MailPaceTransportFactory::class, + MandrillTransportFactory::class, + OhMySmtpTransportFactory::class, + PostmarkTransportFactory::class, + ScalewayTransportFactory::class, + SendgridTransportFactory::class, + SendinblueTransportFactory::class, + SesTransportFactory::class, + ]; + + private iterable $factories; + + public static function fromDsn(#[\SensitiveParameter] string $dsn, ?EventDispatcherInterface $dispatcher = null, ?HttpClientInterface $client = null, ?LoggerInterface $logger = null): TransportInterface + { + $factory = new self(iterator_to_array(self::getDefaultFactories($dispatcher, $client, $logger))); + + return $factory->fromString($dsn); + } + + public static function fromDsns(#[\SensitiveParameter] array $dsns, ?EventDispatcherInterface $dispatcher = null, ?HttpClientInterface $client = null, ?LoggerInterface $logger = null): TransportInterface + { + $factory = new self(iterator_to_array(self::getDefaultFactories($dispatcher, $client, $logger))); + + return $factory->fromStrings($dsns); + } + + /** + * @param TransportFactoryInterface[] $factories + */ + public function __construct(iterable $factories) + { + $this->factories = $factories; + } + + public function fromStrings(#[\SensitiveParameter] array $dsns): Transports + { + $transports = []; + foreach ($dsns as $name => $dsn) { + $transports[$name] = $this->fromString($dsn); + } + + return new Transports($transports); + } + + public function fromString(#[\SensitiveParameter] string $dsn): TransportInterface + { + [$transport, $offset] = $this->parseDsn($dsn); + if ($offset !== \strlen($dsn)) { + throw new InvalidArgumentException('The mailer DSN has some garbage at the end.'); + } + + return $transport; + } + + private function parseDsn(#[\SensitiveParameter] string $dsn, int $offset = 0): array + { + static $keywords = [ + 'failover' => FailoverTransport::class, + 'roundrobin' => RoundRobinTransport::class, + ]; + + while (true) { + foreach ($keywords as $name => $class) { + $name .= '('; + if ($name === substr($dsn, $offset, \strlen($name))) { + $offset += \strlen($name) - 1; + preg_match('{\(([^()]|(?R))*\)}A', $dsn, $matches, 0, $offset); + if (!isset($matches[0])) { + continue; + } + + ++$offset; + $args = []; + while (true) { + [$arg, $offset] = $this->parseDsn($dsn, $offset); + $args[] = $arg; + if (\strlen($dsn) === $offset) { + break; + } + ++$offset; + if (')' === $dsn[$offset - 1]) { + break; + } + } + + return [new $class($args), $offset]; + } + } + + if (preg_match('{(\w+)\(}A', $dsn, $matches, 0, $offset)) { + throw new InvalidArgumentException(\sprintf('The "%s" keyword is not valid (valid ones are "%s"), ', $matches[1], implode('", "', array_keys($keywords)))); + } + + if ($pos = strcspn($dsn, ' )', $offset)) { + return [$this->fromDsnObject(Dsn::fromString(substr($dsn, $offset, $pos))), $offset + $pos]; + } + + return [$this->fromDsnObject(Dsn::fromString(substr($dsn, $offset))), \strlen($dsn)]; + } + } + + public function fromDsnObject(Dsn $dsn): TransportInterface + { + foreach ($this->factories as $factory) { + if ($factory->supports($dsn)) { + return $factory->create($dsn); + } + } + + throw new UnsupportedSchemeException($dsn); + } + + /** + * @return \Traversable + */ + public static function getDefaultFactories(?EventDispatcherInterface $dispatcher = null, ?HttpClientInterface $client = null, ?LoggerInterface $logger = null): \Traversable + { + foreach (self::FACTORY_CLASSES as $factoryClass) { + if (class_exists($factoryClass)) { + yield new $factoryClass($dispatcher, $client, $logger); + } + } + + yield new NullTransportFactory($dispatcher, $client, $logger); + + yield new SendmailTransportFactory($dispatcher, $client, $logger); + + yield new EsmtpTransportFactory($dispatcher, $client, $logger); + + yield new NativeTransportFactory($dispatcher, $client, $logger); + } +} diff --git a/lib/symfony/mailer/Transport/AbstractApiTransport.php b/lib/symfony/mailer/Transport/AbstractApiTransport.php new file mode 100644 index 000000000..6bd49e124 --- /dev/null +++ b/lib/symfony/mailer/Transport/AbstractApiTransport.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\RuntimeException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Email; +use Symfony\Component\Mime\MessageConverter; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Fabien Potencier + */ +abstract class AbstractApiTransport extends AbstractHttpTransport +{ + abstract protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $envelope): ResponseInterface; + + protected function doSendHttp(SentMessage $message): ResponseInterface + { + try { + $email = MessageConverter::toEmail($message->getOriginalMessage()); + } catch (\Exception $e) { + throw new RuntimeException(\sprintf('Unable to send message with the "%s" transport: ', __CLASS__).$e->getMessage(), 0, $e); + } + + return $this->doSendApi($message, $email, $message->getEnvelope()); + } + + /** + * @return Address[] + */ + protected function getRecipients(Email $email, Envelope $envelope): array + { + return array_filter($envelope->getRecipients(), fn (Address $address) => false === \in_array($address, array_merge($email->getCc(), $email->getBcc()), true)); + } +} diff --git a/lib/symfony/mailer/Transport/AbstractHttpTransport.php b/lib/symfony/mailer/Transport/AbstractHttpTransport.php new file mode 100644 index 000000000..ce0feecf0 --- /dev/null +++ b/lib/symfony/mailer/Transport/AbstractHttpTransport.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\HttpClient; +use Symfony\Component\Mailer\Exception\HttpTransportException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Victor Bocharsky + */ +abstract class AbstractHttpTransport extends AbstractTransport +{ + protected $host; + protected $port; + protected $client; + + public function __construct(?HttpClientInterface $client = null, ?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null) + { + $this->client = $client; + if (null === $client) { + if (!class_exists(HttpClient::class)) { + throw new \LogicException(\sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__)); + } + + $this->client = HttpClient::create(); + } + + parent::__construct($dispatcher, $logger); + } + + /** + * @return $this + */ + public function setHost(?string $host): static + { + $this->host = $host; + + return $this; + } + + /** + * @return $this + */ + public function setPort(?int $port): static + { + $this->port = $port; + + return $this; + } + + abstract protected function doSendHttp(SentMessage $message): ResponseInterface; + + protected function doSend(SentMessage $message): void + { + try { + $response = $this->doSendHttp($message); + $message->appendDebug($response->getInfo('debug') ?? ''); + } catch (HttpTransportException $e) { + $e->appendDebug($e->getResponse()->getInfo('debug') ?? ''); + + throw $e; + } + } +} diff --git a/lib/symfony/mailer/Transport/AbstractTransport.php b/lib/symfony/mailer/Transport/AbstractTransport.php new file mode 100644 index 000000000..cff690623 --- /dev/null +++ b/lib/symfony/mailer/Transport/AbstractTransport.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; +use Symfony\Bridge\Twig\Mime\TemplatedEmail; +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Event\FailedMessageEvent; +use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Event\SentMessageEvent; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\BodyRendererInterface; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +abstract class AbstractTransport implements TransportInterface +{ + private ?EventDispatcherInterface $dispatcher; + private LoggerInterface $logger; + private float $rate = 0; + private float $lastSent = 0; + + public function __construct(?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null) + { + $this->dispatcher = $dispatcher; + $this->logger = $logger ?? new NullLogger(); + } + + /** + * Sets the maximum number of messages to send per second (0 to disable). + * + * @return $this + */ + public function setMaxPerSecond(float $rate): static + { + if (0 >= $rate) { + $rate = 0; + } + + $this->rate = $rate; + $this->lastSent = 0; + + return $this; + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + $message = clone $message; + $envelope = null !== $envelope ? clone $envelope : Envelope::create($message); + + try { + if (!$this->dispatcher) { + $sentMessage = new SentMessage($message, $envelope); + $this->doSend($sentMessage); + + return $sentMessage; + } + + $event = new MessageEvent($message, $envelope, (string) $this); + $this->dispatcher->dispatch($event); + if ($event->isRejected()) { + return null; + } + + $envelope = $event->getEnvelope(); + $message = $event->getMessage(); + + if ($message instanceof TemplatedEmail && !$message->isRendered()) { + throw new LogicException(\sprintf('You must configure a "%s" when a "%s" instance has a text or HTML template set.', BodyRendererInterface::class, get_debug_type($message))); + } + + $sentMessage = new SentMessage($message, $envelope); + + try { + $this->doSend($sentMessage); + } catch (\Throwable $error) { + $this->dispatcher->dispatch(new FailedMessageEvent($message, $error)); + $this->checkThrottling(); + + throw $error; + } + + $this->dispatcher->dispatch(new SentMessageEvent($sentMessage)); + + return $sentMessage; + } finally { + $this->checkThrottling(); + } + } + + abstract protected function doSend(SentMessage $message): void; + + /** + * @param Address[] $addresses + * + * @return string[] + */ + protected function stringifyAddresses(array $addresses): array + { + return array_map(fn (Address $a) => $a->toString(), $addresses); + } + + protected function getLogger(): LoggerInterface + { + return $this->logger; + } + + private function checkThrottling(): void + { + if (0 == $this->rate) { + return; + } + + $sleep = (1 / $this->rate) - (microtime(true) - $this->lastSent); + if (0 < $sleep) { + $this->logger->debug(\sprintf('Email transport "%s" sleeps for %.2f seconds', __CLASS__, $sleep)); + usleep((int) ($sleep * 1000000)); + } + $this->lastSent = microtime(true); + } +} diff --git a/lib/symfony/mailer/Transport/AbstractTransportFactory.php b/lib/symfony/mailer/Transport/AbstractTransportFactory.php new file mode 100644 index 000000000..96e90f346 --- /dev/null +++ b/lib/symfony/mailer/Transport/AbstractTransportFactory.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Exception\IncompleteDsnException; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * @author Konstantin Myakshin + */ +abstract class AbstractTransportFactory implements TransportFactoryInterface +{ + protected $dispatcher; + protected $client; + protected $logger; + + public function __construct(?EventDispatcherInterface $dispatcher = null, ?HttpClientInterface $client = null, ?LoggerInterface $logger = null) + { + $this->dispatcher = $dispatcher; + $this->client = $client; + $this->logger = $logger; + } + + public function supports(Dsn $dsn): bool + { + return \in_array($dsn->getScheme(), $this->getSupportedSchemes()); + } + + abstract protected function getSupportedSchemes(): array; + + protected function getUser(Dsn $dsn): string + { + return $dsn->getUser() ?? throw new IncompleteDsnException('User is not set.'); + } + + protected function getPassword(Dsn $dsn): string + { + return $dsn->getPassword() ?? throw new IncompleteDsnException('Password is not set.'); + } +} diff --git a/lib/symfony/mailer/Transport/Dsn.php b/lib/symfony/mailer/Transport/Dsn.php new file mode 100644 index 000000000..0cff6aad1 --- /dev/null +++ b/lib/symfony/mailer/Transport/Dsn.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\InvalidArgumentException; + +/** + * @author Konstantin Myakshin + */ +final class Dsn +{ + private string $scheme; + private string $host; + private ?string $user; + private ?string $password; + private ?int $port; + private array $options; + + public function __construct(string $scheme, string $host, ?string $user = null, #[\SensitiveParameter] ?string $password = null, ?int $port = null, array $options = []) + { + $this->scheme = $scheme; + $this->host = $host; + $this->user = $user; + $this->password = $password; + $this->port = $port; + $this->options = $options; + } + + public static function fromString(#[\SensitiveParameter] string $dsn): self + { + if (false === $params = parse_url($dsn)) { + throw new InvalidArgumentException('The mailer DSN is invalid.'); + } + + if (!isset($params['scheme'])) { + throw new InvalidArgumentException('The mailer DSN must contain a scheme.'); + } + + if (!isset($params['host'])) { + throw new InvalidArgumentException('The mailer DSN must contain a host (use "default" by default).'); + } + + $user = '' !== ($params['user'] ?? '') ? rawurldecode($params['user']) : null; + $password = '' !== ($params['pass'] ?? '') ? rawurldecode($params['pass']) : null; + $port = $params['port'] ?? null; + parse_str($params['query'] ?? '', $query); + + return new self($params['scheme'], $params['host'], $user, $password, $port, $query); + } + + public function getScheme(): string + { + return $this->scheme; + } + + public function getHost(): string + { + return $this->host; + } + + public function getUser(): ?string + { + return $this->user; + } + + public function getPassword(): ?string + { + return $this->password; + } + + public function getPort(?int $default = null): ?int + { + return $this->port ?? $default; + } + + public function getOption(string $key, mixed $default = null): mixed + { + return $this->options[$key] ?? $default; + } +} diff --git a/lib/symfony/mailer/Transport/FailoverTransport.php b/lib/symfony/mailer/Transport/FailoverTransport.php new file mode 100644 index 000000000..d6a747730 --- /dev/null +++ b/lib/symfony/mailer/Transport/FailoverTransport.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +/** + * Uses several Transports using a failover algorithm. + * + * @author Fabien Potencier + */ +class FailoverTransport extends RoundRobinTransport +{ + private ?TransportInterface $currentTransport = null; + + protected function getNextTransport(): ?TransportInterface + { + if (null === $this->currentTransport || $this->isTransportDead($this->currentTransport)) { + $this->currentTransport = parent::getNextTransport(); + } + + return $this->currentTransport; + } + + protected function getInitialCursor(): int + { + return 0; + } + + protected function getNameSymbol(): string + { + return 'failover'; + } +} diff --git a/lib/symfony/mailer/Transport/NativeTransportFactory.php b/lib/symfony/mailer/Transport/NativeTransportFactory.php new file mode 100644 index 000000000..8afa53cc4 --- /dev/null +++ b/lib/symfony/mailer/Transport/NativeTransportFactory.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; +use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; + +/** + * Factory that configures a transport (sendmail or SMTP) based on php.ini settings. + * + * @author Laurent VOULLEMIER + */ +final class NativeTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + if (!\in_array($dsn->getScheme(), $this->getSupportedSchemes(), true)) { + throw new UnsupportedSchemeException($dsn, 'native', $this->getSupportedSchemes()); + } + + if ($sendMailPath = ini_get('sendmail_path')) { + return new SendmailTransport($sendMailPath, $this->dispatcher, $this->logger); + } + + if ('\\' !== \DIRECTORY_SEPARATOR) { + throw new TransportException('sendmail_path is not configured in php.ini.'); + } + + // Only for windows hosts; at this point non-windows + // host have already thrown an exception or returned a transport + $host = ini_get('SMTP'); + $port = (int) ini_get('smtp_port'); + + if (!$host || !$port) { + throw new TransportException('smtp or smtp_port is not configured in php.ini.'); + } + + $socketStream = new SocketStream(); + $socketStream->setHost($host); + $socketStream->setPort($port); + if (465 !== $port) { + $socketStream->disableTls(); + } + + return new SmtpTransport($socketStream, $this->dispatcher, $this->logger); + } + + protected function getSupportedSchemes(): array + { + return ['native']; + } +} diff --git a/lib/symfony/mailer/Transport/NullTransport.php b/lib/symfony/mailer/Transport/NullTransport.php new file mode 100644 index 000000000..92fb82a47 --- /dev/null +++ b/lib/symfony/mailer/Transport/NullTransport.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\SentMessage; + +/** + * Pretends messages have been sent, but just ignores them. + * + * @author Fabien Potencier + */ +final class NullTransport extends AbstractTransport +{ + protected function doSend(SentMessage $message): void + { + } + + public function __toString(): string + { + return 'null://'; + } +} diff --git a/lib/symfony/mailer/Transport/NullTransportFactory.php b/lib/symfony/mailer/Transport/NullTransportFactory.php new file mode 100644 index 000000000..4c45f39e1 --- /dev/null +++ b/lib/symfony/mailer/Transport/NullTransportFactory.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; + +/** + * @author Konstantin Myakshin + */ +final class NullTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + if ('null' === $dsn->getScheme()) { + return new NullTransport($this->dispatcher, $this->logger); + } + + throw new UnsupportedSchemeException($dsn, 'null', $this->getSupportedSchemes()); + } + + protected function getSupportedSchemes(): array + { + return ['null']; + } +} diff --git a/lib/symfony/mailer/Transport/RoundRobinTransport.php b/lib/symfony/mailer/Transport/RoundRobinTransport.php new file mode 100644 index 000000000..25656396c --- /dev/null +++ b/lib/symfony/mailer/Transport/RoundRobinTransport.php @@ -0,0 +1,125 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\RawMessage; + +/** + * Uses several Transports using a round robin algorithm. + * + * @author Fabien Potencier + */ +class RoundRobinTransport implements TransportInterface +{ + /** + * @var \SplObjectStorage + */ + private \SplObjectStorage $deadTransports; + private array $transports = []; + private int $retryPeriod; + private int $cursor = -1; + + /** + * @param TransportInterface[] $transports + */ + public function __construct(array $transports, int $retryPeriod = 60) + { + if (!$transports) { + throw new TransportException(\sprintf('"%s" must have at least one transport configured.', static::class)); + } + + $this->transports = $transports; + $this->deadTransports = new \SplObjectStorage(); + $this->retryPeriod = $retryPeriod; + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + $exception = null; + + while ($transport = $this->getNextTransport()) { + try { + return $transport->send(clone $message, $envelope); + } catch (TransportExceptionInterface $e) { + $exception ??= new TransportException('All transports failed.'); + $exception->appendDebug(\sprintf("Transport \"%s\": %s\n", $transport, $e->getDebug())); + $this->deadTransports[$transport] = microtime(true); + } + } + + throw $exception ?? new TransportException('No transports found.'); + } + + public function __toString(): string + { + return $this->getNameSymbol().'('.implode(' ', array_map('strval', $this->transports)).')'; + } + + /** + * Rotates the transport list around and returns the first instance. + */ + protected function getNextTransport(): ?TransportInterface + { + if (-1 === $this->cursor) { + $this->cursor = $this->getInitialCursor(); + } + + $cursor = $this->cursor; + while (true) { + $transport = $this->transports[$cursor]; + + if (!$this->isTransportDead($transport)) { + break; + } + + if ((microtime(true) - $this->deadTransports[$transport]) > $this->retryPeriod) { + unset($this->deadTransports[$transport]); + + break; + } + + if ($this->cursor === $cursor = $this->moveCursor($cursor)) { + return null; + } + } + + $this->cursor = $this->moveCursor($cursor); + + return $transport; + } + + protected function isTransportDead(TransportInterface $transport): bool + { + return $this->deadTransports->offsetExists($transport); + } + + protected function getInitialCursor(): int + { + // the cursor initial value is randomized so that + // when are not in a daemon, we are still rotating the transports + return mt_rand(0, \count($this->transports) - 1); + } + + protected function getNameSymbol(): string + { + return 'roundrobin'; + } + + private function moveCursor(int $cursor): int + { + return ++$cursor >= \count($this->transports) ? 0 : $cursor; + } +} diff --git a/lib/symfony/mailer/Transport/SendmailTransport.php b/lib/symfony/mailer/Transport/SendmailTransport.php new file mode 100644 index 000000000..45cf503e1 --- /dev/null +++ b/lib/symfony/mailer/Transport/SendmailTransport.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport; +use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream; +use Symfony\Component\Mailer\Transport\Smtp\Stream\ProcessStream; +use Symfony\Component\Mime\RawMessage; + +/** + * SendmailTransport for sending mail through a Sendmail/Postfix (etc..) binary. + * + * Transport can be instantiated through SendmailTransportFactory or NativeTransportFactory: + * + * - SendmailTransportFactory to use most common sendmail path and recommended options + * - NativeTransportFactory when configuration is set via php.ini + * + * @author Fabien Potencier + * @author Chris Corbyn + */ +class SendmailTransport extends AbstractTransport +{ + private string $command = '/usr/sbin/sendmail -bs'; + private ProcessStream $stream; + private ?SmtpTransport $transport = null; + + /** + * Constructor. + * + * Supported modes are -bs and -t, with any additional flags desired. + * + * The recommended mode is "-bs" since it is interactive and failure notifications are hence possible. + * Note that the -t mode does not support error reporting and does not support Bcc properly (the Bcc headers are not removed). + * + * If using -t mode, you are strongly advised to include -oi or -i in the flags (like /usr/sbin/sendmail -oi -t) + * + * -f flag will be appended automatically if one is not present. + */ + public function __construct(?string $command = null, ?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null) + { + parent::__construct($dispatcher, $logger); + + if (null !== $command) { + if (!str_contains($command, ' -bs') && !str_contains($command, ' -t')) { + throw new \InvalidArgumentException(\sprintf('Unsupported sendmail command flags "%s"; must be one of "-bs" or "-t" but can include additional flags.', $command)); + } + + $this->command = $command; + } + + $this->stream = new ProcessStream(); + if (str_contains($this->command, ' -bs')) { + $this->stream->setCommand($this->command); + $this->stream->setInteractive(true); + $this->transport = new SmtpTransport($this->stream, $dispatcher, $logger); + } + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + if ($this->transport) { + return $this->transport->send($message, $envelope); + } + + return parent::send($message, $envelope); + } + + public function __toString(): string + { + if ($this->transport) { + return (string) $this->transport; + } + + return 'smtp://sendmail'; + } + + protected function doSend(SentMessage $message): void + { + $this->getLogger()->debug(\sprintf('Email transport "%s" starting', __CLASS__)); + + $command = $this->command; + + if ($recipients = $message->getEnvelope()->getRecipients()) { + $command = str_replace(' -t', '', $command); + } + + if (!str_contains($command, ' -f')) { + $command .= ' -f'.escapeshellarg($message->getEnvelope()->getSender()->getEncodedAddress()); + } + + $chunks = AbstractStream::replace("\r\n", "\n", $message->toIterable()); + + if (!str_contains($command, ' -i') && !str_contains($command, ' -oi')) { + $chunks = AbstractStream::replace("\n.", "\n..", $chunks); + } + + foreach ($recipients as $recipient) { + $command .= ' '.escapeshellarg($recipient->getEncodedAddress()); + } + + $this->stream->setCommand($command); + $this->stream->initialize(); + foreach ($chunks as $chunk) { + $this->stream->write($chunk, false); + } + $this->stream->flush(); + $this->stream->terminate(); + + $this->getLogger()->debug(\sprintf('Email transport "%s" stopped', __CLASS__)); + } +} diff --git a/lib/symfony/mailer/Transport/SendmailTransportFactory.php b/lib/symfony/mailer/Transport/SendmailTransportFactory.php new file mode 100644 index 000000000..6d977e74b --- /dev/null +++ b/lib/symfony/mailer/Transport/SendmailTransportFactory.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; + +/** + * @author Konstantin Myakshin + */ +final class SendmailTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + if ('sendmail+smtp' === $dsn->getScheme() || 'sendmail' === $dsn->getScheme()) { + return new SendmailTransport($dsn->getOption('command'), $this->dispatcher, $this->logger); + } + + throw new UnsupportedSchemeException($dsn, 'sendmail', $this->getSupportedSchemes()); + } + + protected function getSupportedSchemes(): array + { + return ['sendmail', 'sendmail+smtp']; + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php b/lib/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php new file mode 100644 index 000000000..98ea2d44a --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/Auth/AuthenticatorInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * An Authentication mechanism. + * + * @author Chris Corbyn + */ +interface AuthenticatorInterface +{ + /** + * Tries to authenticate the user. + * + * @throws TransportExceptionInterface + */ + public function authenticate(EsmtpTransport $client): void; + + /** + * Gets the name of the AUTH mechanism this Authenticator handles. + */ + public function getAuthKeyword(): string; +} diff --git a/lib/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php b/lib/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php new file mode 100644 index 000000000..119051938 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/Auth/CramMd5Authenticator.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * Handles CRAM-MD5 authentication. + * + * @author Chris Corbyn + */ +class CramMd5Authenticator implements AuthenticatorInterface +{ + public function getAuthKeyword(): string + { + return 'CRAM-MD5'; + } + + /** + * @see https://www.ietf.org/rfc/rfc4954.txt + */ + public function authenticate(EsmtpTransport $client): void + { + $challenge = $client->executeCommand("AUTH CRAM-MD5\r\n", [334]); + $challenge = base64_decode(substr($challenge, 4)); + $message = base64_encode($client->getUsername().' '.$this->getResponse($client->getPassword(), $challenge)); + $client->executeCommand(\sprintf("%s\r\n", $message), [235]); + } + + /** + * Generates a CRAM-MD5 response from a server challenge. + */ + private function getResponse(#[\SensitiveParameter] string $secret, string $challenge): string + { + if (!$secret) { + throw new InvalidArgumentException('A non-empty secret is required.'); + } + + if (\strlen($secret) > 64) { + $secret = pack('H32', md5($secret)); + } + + if (\strlen($secret) < 64) { + $secret = str_pad($secret, 64, \chr(0)); + } + + $kipad = substr($secret, 0, 64) ^ str_repeat(\chr(0x36), 64); + $kopad = substr($secret, 0, 64) ^ str_repeat(\chr(0x5C), 64); + + $inner = pack('H32', md5($kipad.$challenge)); + $digest = md5($kopad.$inner); + + return $digest; + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php b/lib/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php new file mode 100644 index 000000000..82fe45366 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/Auth/LoginAuthenticator.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * Handles LOGIN authentication. + * + * @author Chris Corbyn + */ +class LoginAuthenticator implements AuthenticatorInterface +{ + public function getAuthKeyword(): string + { + return 'LOGIN'; + } + + /** + * @see https://www.ietf.org/rfc/rfc4954.txt + */ + public function authenticate(EsmtpTransport $client): void + { + $client->executeCommand("AUTH LOGIN\r\n", [334]); + $client->executeCommand(\sprintf("%s\r\n", base64_encode($client->getUsername())), [334]); + $client->executeCommand(\sprintf("%s\r\n", base64_encode($client->getPassword())), [235]); + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php b/lib/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php new file mode 100644 index 000000000..7a6fefa15 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/Auth/PlainAuthenticator.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * Handles PLAIN authentication. + * + * @author Chris Corbyn + */ +class PlainAuthenticator implements AuthenticatorInterface +{ + public function getAuthKeyword(): string + { + return 'PLAIN'; + } + + /** + * @see https://www.ietf.org/rfc/rfc4954.txt + */ + public function authenticate(EsmtpTransport $client): void + { + $client->executeCommand(\sprintf("AUTH PLAIN %s\r\n", base64_encode($client->getUsername().\chr(0).$client->getUsername().\chr(0).$client->getPassword())), [235]); + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php b/lib/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php new file mode 100644 index 000000000..c3aaa4909 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Auth; + +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; + +/** + * Handles XOAUTH2 authentication. + * + * @author xu.li + * + * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol + */ +class XOAuth2Authenticator implements AuthenticatorInterface +{ + public function getAuthKeyword(): string + { + return 'XOAUTH2'; + } + + /** + * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol#the_sasl_xoauth2_mechanism + */ + public function authenticate(EsmtpTransport $client): void + { + $client->executeCommand('AUTH XOAUTH2 '.base64_encode('user='.$client->getUsername()."\1auth=Bearer ".$client->getPassword()."\1\1")."\r\n", [235]); + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/EsmtpTransport.php b/lib/symfony/mailer/Transport/Smtp/EsmtpTransport.php new file mode 100644 index 000000000..05ca155cd --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/EsmtpTransport.php @@ -0,0 +1,228 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Exception\UnexpectedResponseException; +use Symfony\Component\Mailer\Transport\Smtp\Auth\AuthenticatorInterface; +use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; + +/** + * Sends Emails over SMTP with ESMTP support. + * + * @author Fabien Potencier + * @author Chris Corbyn + */ +class EsmtpTransport extends SmtpTransport +{ + private array $authenticators = []; + private string $username = ''; + private string $password = ''; + private array $capabilities; + + public function __construct(string $host = 'localhost', int $port = 0, ?bool $tls = null, ?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null, ?AbstractStream $stream = null, ?array $authenticators = null) + { + parent::__construct($stream, $dispatcher, $logger); + + if (null === $authenticators) { + // fallback to default authenticators + // order is important here (roughly most secure and popular first) + $authenticators = [ + new Auth\CramMd5Authenticator(), + new Auth\LoginAuthenticator(), + new Auth\PlainAuthenticator(), + new Auth\XOAuth2Authenticator(), + ]; + } + $this->setAuthenticators($authenticators); + + /** @var SocketStream $stream */ + $stream = $this->getStream(); + + if (null === $tls) { + if (465 === $port) { + $tls = true; + } else { + $tls = \defined('OPENSSL_VERSION_NUMBER') && 0 === $port && 'localhost' !== $host; + } + } + if (!$tls) { + $stream->disableTls(); + } + if (0 === $port) { + $port = $tls ? 465 : 25; + } + + $stream->setHost($host); + $stream->setPort($port); + } + + /** + * @return $this + */ + public function setUsername(string $username): static + { + $this->username = $username; + + return $this; + } + + public function getUsername(): string + { + return $this->username; + } + + /** + * @return $this + */ + public function setPassword(#[\SensitiveParameter] string $password): static + { + $this->password = $password; + + return $this; + } + + public function getPassword(): string + { + return $this->password; + } + + public function setAuthenticators(array $authenticators): void + { + $this->authenticators = []; + foreach ($authenticators as $authenticator) { + $this->addAuthenticator($authenticator); + } + } + + public function addAuthenticator(AuthenticatorInterface $authenticator): void + { + $this->authenticators[] = $authenticator; + } + + public function executeCommand(string $command, array $codes): string + { + return [250] === $codes && str_starts_with($command, 'HELO ') ? $this->doEhloCommand() : parent::executeCommand($command, $codes); + } + + final protected function getCapabilities(): array + { + return $this->capabilities; + } + + private function doEhloCommand(): string + { + try { + $response = $this->executeCommand(\sprintf("EHLO %s\r\n", $this->getLocalDomain()), [250]); + } catch (TransportExceptionInterface $e) { + try { + return parent::executeCommand(\sprintf("HELO %s\r\n", $this->getLocalDomain()), [250]); + } catch (TransportExceptionInterface $ex) { + if (!$ex->getCode()) { + throw $e; + } + + throw $ex; + } + } + + $this->capabilities = $this->parseCapabilities($response); + + /** @var SocketStream $stream */ + $stream = $this->getStream(); + // WARNING: !$stream->isTLS() is right, 100% sure :) + // if you think that the ! should be removed, read the code again + // if doing so "fixes" your issue then it probably means your SMTP server behaves incorrectly or is wrongly configured + if (!$stream->isTLS() && \defined('OPENSSL_VERSION_NUMBER') && \array_key_exists('STARTTLS', $this->capabilities)) { + $this->executeCommand("STARTTLS\r\n", [220]); + + if (!$stream->startTLS()) { + throw new TransportException('Unable to connect with STARTTLS.'); + } + + $response = $this->executeCommand(\sprintf("EHLO %s\r\n", $this->getLocalDomain()), [250]); + $this->capabilities = $this->parseCapabilities($response); + } + + if (\array_key_exists('AUTH', $this->capabilities)) { + $this->handleAuth($this->capabilities['AUTH']); + } + + return $response; + } + + private function parseCapabilities(string $ehloResponse): array + { + $capabilities = []; + $lines = explode("\r\n", trim($ehloResponse)); + array_shift($lines); + foreach ($lines as $line) { + if (preg_match('/^[0-9]{3}[ -]([A-Z0-9-]+)((?:[ =].*)?)$/Di', $line, $matches)) { + $value = strtoupper(ltrim($matches[2], ' =')); + $capabilities[strtoupper($matches[1])] = $value ? explode(' ', $value) : []; + } + } + + return $capabilities; + } + + private function handleAuth(array $modes): void + { + if (!$this->username) { + return; + } + + $code = null; + $authNames = []; + $errors = []; + $modes = array_map('strtolower', $modes); + foreach ($this->authenticators as $authenticator) { + if (!\in_array(strtolower($authenticator->getAuthKeyword()), $modes, true)) { + continue; + } + + $code = null; + $authNames[] = $authenticator->getAuthKeyword(); + try { + $authenticator->authenticate($this); + + return; + } catch (UnexpectedResponseException $e) { + $code = $e->getCode(); + + try { + $this->executeCommand("RSET\r\n", [250]); + } catch (TransportExceptionInterface) { + // ignore this exception as it probably means that the server error was final + } + + // keep the error message, but tries the other authenticators + $errors[$authenticator->getAuthKeyword()] = $e->getMessage(); + } + } + + if (!$authNames) { + throw new TransportException(\sprintf('Failed to find an authenticator supported by the SMTP server, which currently supports: "%s".', implode('", "', $modes)), $code ?: 504); + } + + $message = \sprintf('Failed to authenticate on SMTP server with username "%s" using the following authenticators: "%s".', $this->username, implode('", "', $authNames)); + foreach ($errors as $name => $error) { + $message .= \sprintf(' Authenticator "%s" returned "%s".', $name, $error); + } + + throw new TransportException($message, $code ?: 535); + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php b/lib/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php new file mode 100644 index 000000000..a15d12245 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/EsmtpTransportFactory.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp; + +use Symfony\Component\Mailer\Transport\AbstractTransportFactory; +use Symfony\Component\Mailer\Transport\Dsn; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; +use Symfony\Component\Mailer\Transport\TransportInterface; + +/** + * @author Konstantin Myakshin + */ +final class EsmtpTransportFactory extends AbstractTransportFactory +{ + public function create(Dsn $dsn): TransportInterface + { + $tls = 'smtps' === $dsn->getScheme() ? true : null; + $port = $dsn->getPort(0); + $host = $dsn->getHost(); + + $transport = new EsmtpTransport($host, $port, $tls, $this->dispatcher, $this->logger); + + /** @var SocketStream $stream */ + $stream = $transport->getStream(); + $streamOptions = $stream->getStreamOptions(); + + if ('' !== $dsn->getOption('verify_peer') && !filter_var($dsn->getOption('verify_peer', true), \FILTER_VALIDATE_BOOL)) { + $streamOptions['ssl']['verify_peer'] = false; + $streamOptions['ssl']['verify_peer_name'] = false; + } + + if (null !== $peerFingerprint = $dsn->getOption('peer_fingerprint')) { + $streamOptions['ssl']['peer_fingerprint'] = $peerFingerprint; + } + + $stream->setStreamOptions($streamOptions); + + if ($user = $dsn->getUser()) { + $transport->setUsername($user); + } + + if ($password = $dsn->getPassword()) { + $transport->setPassword($password); + } + + if (null !== ($localDomain = $dsn->getOption('local_domain'))) { + $transport->setLocalDomain($localDomain); + } + + if (null !== ($maxPerSecond = $dsn->getOption('max_per_second'))) { + $transport->setMaxPerSecond((float) $maxPerSecond); + } + + if (null !== ($restartThreshold = $dsn->getOption('restart_threshold'))) { + $transport->setRestartThreshold((int) $restartThreshold, (int) $dsn->getOption('restart_threshold_sleep', 0)); + } + + if (null !== ($pingThreshold = $dsn->getOption('ping_threshold'))) { + $transport->setPingThreshold((int) $pingThreshold); + } + + return $transport; + } + + protected function getSupportedSchemes(): array + { + return ['smtp', 'smtps']; + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/SmtpTransport.php b/lib/symfony/mailer/Transport/Smtp/SmtpTransport.php new file mode 100644 index 000000000..ee37516e1 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/SmtpTransport.php @@ -0,0 +1,392 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp; + +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Exception\UnexpectedResponseException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mailer\Transport\AbstractTransport; +use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; +use Symfony\Component\Mime\RawMessage; + +/** + * Sends emails over SMTP. + * + * @author Fabien Potencier + * @author Chris Corbyn + */ +class SmtpTransport extends AbstractTransport +{ + private bool $started = false; + private int $restartThreshold = 100; + private int $restartThresholdSleep = 0; + private int $restartCounter = 0; + private int $pingThreshold = 100; + private float $lastMessageTime = 0; + private AbstractStream $stream; + private string $domain = '[127.0.0.1]'; + + public function __construct(?AbstractStream $stream = null, ?EventDispatcherInterface $dispatcher = null, ?LoggerInterface $logger = null) + { + parent::__construct($dispatcher, $logger); + + $this->stream = $stream ?? new SocketStream(); + } + + public function getStream(): AbstractStream + { + return $this->stream; + } + + /** + * Sets the maximum number of messages to send before re-starting the transport. + * + * By default, the threshold is set to 100 (and no sleep at restart). + * + * @param int $threshold The maximum number of messages (0 to disable) + * @param int $sleep The number of seconds to sleep between stopping and re-starting the transport + * + * @return $this + */ + public function setRestartThreshold(int $threshold, int $sleep = 0): static + { + $this->restartThreshold = $threshold; + $this->restartThresholdSleep = $sleep; + + return $this; + } + + /** + * Sets the minimum number of seconds required between two messages, before the server is pinged. + * If the transport wants to send a message and the time since the last message exceeds the specified threshold, + * the transport will ping the server first (NOOP command) to check if the connection is still alive. + * Otherwise the message will be sent without pinging the server first. + * + * Do not set the threshold too low, as the SMTP server may drop the connection if there are too many + * non-mail commands (like pinging the server with NOOP). + * + * By default, the threshold is set to 100 seconds. + * + * @param int $seconds The minimum number of seconds between two messages required to ping the server + * + * @return $this + */ + public function setPingThreshold(int $seconds): static + { + $this->pingThreshold = $seconds; + + return $this; + } + + /** + * Sets the name of the local domain that will be used in HELO. + * + * This should be a fully-qualified domain name and should be truly the domain + * you're using. + * + * If your server does not have a domain name, use the IP address. This will + * automatically be wrapped in square brackets as described in RFC 5321, + * section 4.1.3. + * + * @return $this + */ + public function setLocalDomain(string $domain): static + { + if ('' !== $domain && '[' !== $domain[0]) { + if (filter_var($domain, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { + $domain = '['.$domain.']'; + } elseif (filter_var($domain, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + $domain = '[IPv6:'.$domain.']'; + } + } + + $this->domain = $domain; + + return $this; + } + + /** + * Gets the name of the domain that will be used in HELO. + * + * If an IP address was specified, this will be returned wrapped in square + * brackets as described in RFC 5321, section 4.1.3. + */ + public function getLocalDomain(): string + { + return $this->domain; + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + try { + $message = parent::send($message, $envelope); + } catch (TransportExceptionInterface $e) { + if ($this->started) { + try { + $this->executeCommand("RSET\r\n", [250]); + } catch (TransportExceptionInterface) { + // ignore this exception as it probably means that the server error was final + } + } + + throw $e; + } + + $this->checkRestartThreshold(); + + return $message; + } + + protected function parseMessageId(string $mtaResult): string + { + $regexps = [ + '/250 Ok (?P[0-9a-f-]+)\r?$/mis', + '/250 Ok:? queued as (?P[A-Z0-9]+)\r?$/mis', + ]; + $matches = []; + foreach ($regexps as $regexp) { + if (preg_match($regexp, $mtaResult, $matches)) { + return $matches['id']; + } + } + + return ''; + } + + public function __toString(): string + { + if ($this->stream instanceof SocketStream) { + $name = \sprintf('smtp%s://%s', ($tls = $this->stream->isTLS()) ? 's' : '', $this->stream->getHost()); + $port = $this->stream->getPort(); + if (!(25 === $port || ($tls && 465 === $port))) { + $name .= ':'.$port; + } + + return $name; + } + + return 'smtp://sendmail'; + } + + /** + * Runs a command against the stream, expecting the given response codes. + * + * @param int[] $codes + * + * @throws TransportException when an invalid response if received + */ + public function executeCommand(string $command, array $codes): string + { + $this->stream->write($command); + $response = $this->getFullResponse(); + $this->assertResponseCode($response, $codes); + + return $response; + } + + protected function doSend(SentMessage $message): void + { + if (microtime(true) - $this->lastMessageTime > $this->pingThreshold) { + $this->ping(); + } + + try { + if (!$this->started) { + $this->start(); + } + + $envelope = $message->getEnvelope(); + $this->doMailFromCommand($envelope->getSender()->getEncodedAddress()); + foreach ($envelope->getRecipients() as $recipient) { + $this->doRcptToCommand($recipient->getEncodedAddress()); + } + + $this->executeCommand("DATA\r\n", [354]); + try { + foreach (AbstractStream::replace("\r\n.", "\r\n..", $message->toIterable()) as $chunk) { + $this->stream->write($chunk, false); + } + $this->stream->flush(); + } catch (TransportExceptionInterface $e) { + throw $e; + } catch (\Exception $e) { + $this->stream->terminate(); + $this->started = false; + $this->getLogger()->debug(\sprintf('Email transport "%s" stopped', __CLASS__)); + throw $e; + } + $mtaResult = $this->executeCommand("\r\n.\r\n", [250]); + $message->appendDebug($this->stream->getDebug()); + $this->lastMessageTime = microtime(true); + + if ($mtaResult && $messageId = $this->parseMessageId($mtaResult)) { + $message->setMessageId($messageId); + } + } catch (TransportExceptionInterface $e) { + $e->appendDebug($this->stream->getDebug()); + $this->lastMessageTime = 0; + throw $e; + } + } + + /** + * @internal since version 6.1, to be made private in 7.0 + * + * @final since version 6.1, to be made private in 7.0 + */ + protected function doHeloCommand(): void + { + $this->executeCommand(\sprintf("HELO %s\r\n", $this->domain), [250]); + } + + private function doMailFromCommand(string $address): void + { + $this->executeCommand(\sprintf("MAIL FROM:<%s>\r\n", $address), [250]); + } + + private function doRcptToCommand(string $address): void + { + $this->executeCommand(\sprintf("RCPT TO:<%s>\r\n", $address), [250, 251, 252]); + } + + public function start(): void + { + if ($this->started) { + return; + } + + $this->getLogger()->debug(\sprintf('Email transport "%s" starting', __CLASS__)); + + $this->stream->initialize(); + $this->assertResponseCode($this->getFullResponse(), [220]); + $this->doHeloCommand(); + $this->started = true; + $this->lastMessageTime = 0; + + $this->getLogger()->debug(\sprintf('Email transport "%s" started', __CLASS__)); + } + + /** + * Manually disconnect from the SMTP server. + * + * In most cases this is not necessary since the disconnect happens automatically on termination. + * In cases of long-running scripts, this might however make sense to avoid keeping an open + * connection to the SMTP server in between sending emails. + */ + public function stop(): void + { + if (!$this->started) { + return; + } + + $this->getLogger()->debug(\sprintf('Email transport "%s" stopping', __CLASS__)); + + try { + $this->executeCommand("QUIT\r\n", [221]); + } catch (TransportExceptionInterface) { + } finally { + $this->stream->terminate(); + $this->started = false; + $this->getLogger()->debug(\sprintf('Email transport "%s" stopped', __CLASS__)); + } + } + + private function ping(): void + { + if (!$this->started) { + return; + } + + try { + $this->executeCommand("NOOP\r\n", [250]); + } catch (TransportExceptionInterface) { + $this->stop(); + } + } + + /** + * @throws TransportException if a response code is incorrect + */ + private function assertResponseCode(string $response, array $codes): void + { + if (!$codes) { + throw new LogicException('You must set the expected response code.'); + } + + [$code] = sscanf($response, '%3d'); + $valid = \in_array($code, $codes); + + if (!$valid || !$response) { + $codeStr = $code ? \sprintf('code "%s"', $code) : 'empty code'; + $responseStr = $response ? \sprintf(', with message "%s"', trim($response)) : ''; + + throw new UnexpectedResponseException(\sprintf('Expected response code "%s" but got ', implode('/', $codes)).$codeStr.$responseStr.'.', $code ?: 0); + } + } + + private function getFullResponse(): string + { + $response = ''; + do { + $line = $this->stream->readLine(); + $response .= $line; + } while ($line && isset($line[3]) && ' ' !== $line[3]); + + return $response; + } + + private function checkRestartThreshold(): void + { + // when using sendmail via non-interactive mode, the transport is never "started" + if (!$this->started) { + return; + } + + ++$this->restartCounter; + if ($this->restartCounter < $this->restartThreshold) { + return; + } + + $this->stop(); + if (0 < $sleep = $this->restartThresholdSleep) { + $this->getLogger()->debug(\sprintf('Email transport "%s" sleeps for %d seconds after stopping', __CLASS__, $sleep)); + + sleep($sleep); + } + $this->start(); + $this->restartCounter = 0; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + /** + * @return void + */ + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + $this->stop(); + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php b/lib/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php new file mode 100644 index 000000000..8363063a9 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/Stream/AbstractStream.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Stream; + +use Symfony\Component\Mailer\Exception\TransportException; + +/** + * A stream supporting remote sockets and local processes. + * + * @author Fabien Potencier + * @author Nicolas Grekas + * @author Chris Corbyn + * + * @internal + */ +abstract class AbstractStream +{ + /** @var resource|null */ + protected $stream; + /** @var resource|null */ + protected $in; + /** @var resource|null */ + protected $out; + protected $err; + + private string $debug = ''; + + public function write(string $bytes, bool $debug = true): void + { + if ($debug) { + foreach (explode("\n", trim($bytes)) as $line) { + $this->debug .= \sprintf("> %s\n", $line); + } + } + + $bytesToWrite = \strlen($bytes); + $totalBytesWritten = 0; + while ($totalBytesWritten < $bytesToWrite) { + $bytesWritten = @fwrite($this->in, substr($bytes, $totalBytesWritten)); + if (false === $bytesWritten || 0 === $bytesWritten) { + throw new TransportException('Unable to write bytes on the wire.'); + } + + $totalBytesWritten += $bytesWritten; + } + } + + /** + * Flushes the contents of the stream (empty it) and set the internal pointer to the beginning. + */ + public function flush(): void + { + fflush($this->in); + } + + /** + * Performs any initialization needed. + */ + abstract public function initialize(): void; + + public function terminate(): void + { + $this->stream = $this->err = $this->out = $this->in = null; + } + + public function readLine(): string + { + if (feof($this->out)) { + return ''; + } + + $line = @fgets($this->out); + if ('' === $line || false === $line) { + if (stream_get_meta_data($this->out)['timed_out']) { + throw new TransportException(\sprintf('Connection to "%s" timed out.', $this->getReadConnectionDescription())); + } + if (feof($this->out)) { // don't use "eof" metadata, it's not accurate on Windows + throw new TransportException(\sprintf('Connection to "%s" has been closed unexpectedly.', $this->getReadConnectionDescription())); + } + if (false === $line) { + throw new TransportException(\sprintf('Unable to read from connection to "%s": ', $this->getReadConnectionDescription().error_get_last()['message'] ?? '')); + } + } + + $this->debug .= \sprintf('< %s', $line); + + return $line; + } + + public function getDebug(): string + { + $debug = $this->debug; + $this->debug = ''; + + return $debug; + } + + public static function replace(string $from, string $to, iterable $chunks): \Generator + { + if ('' === $from) { + yield from $chunks; + + return; + } + + $carry = ''; + $fromLen = \strlen($from); + + foreach ($chunks as $chunk) { + if ('' === $chunk = $carry.$chunk) { + continue; + } + + if (str_contains($chunk, $from)) { + $chunk = explode($from, $chunk); + $carry = array_pop($chunk); + + yield implode($to, $chunk).$to; + } else { + $carry = $chunk; + } + + if (\strlen($carry) > $fromLen) { + yield substr($carry, 0, -$fromLen); + $carry = substr($carry, -$fromLen); + } + } + + if ('' !== $carry) { + yield $carry; + } + } + + abstract protected function getReadConnectionDescription(): string; +} diff --git a/lib/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php b/lib/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php new file mode 100644 index 000000000..e63514709 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/Stream/ProcessStream.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Stream; + +use Symfony\Component\Mailer\Exception\TransportException; + +/** + * A stream supporting local processes. + * + * @author Fabien Potencier + * @author Chris Corbyn + * + * @internal + */ +final class ProcessStream extends AbstractStream +{ + private string $command; + private bool $interactive = false; + + public function setCommand(string $command): void + { + $this->command = $command; + } + + public function setInteractive(bool $interactive): void + { + $this->interactive = $interactive; + } + + public function initialize(): void + { + $descriptorSpec = [ + 0 => ['pipe', 'r'], + 1 => ['pipe', 'w'], + 2 => ['pipe', '\\' === \DIRECTORY_SEPARATOR ? 'a' : 'w'], + ]; + $pipes = []; + $this->stream = proc_open($this->command, $descriptorSpec, $pipes); + stream_set_blocking($pipes[2], false); + if ($err = stream_get_contents($pipes[2])) { + throw new TransportException('Process could not be started: '.$err); + } + $this->in = &$pipes[0]; + $this->out = &$pipes[1]; + $this->err = &$pipes[2]; + } + + public function terminate(): void + { + if (null !== $this->stream) { + fclose($this->in); + $out = stream_get_contents($this->out); + fclose($this->out); + $err = stream_get_contents($this->err); + fclose($this->err); + if (0 !== $exitCode = proc_close($this->stream)) { + $errorMessage = 'Process failed with exit code '.$exitCode.': '.$out.$err; + } + } + + parent::terminate(); + + if (!$this->interactive && isset($errorMessage)) { + throw new TransportException($errorMessage); + } + } + + protected function getReadConnectionDescription(): string + { + return 'process '.$this->command; + } +} diff --git a/lib/symfony/mailer/Transport/Smtp/Stream/SocketStream.php b/lib/symfony/mailer/Transport/Smtp/Stream/SocketStream.php new file mode 100644 index 000000000..560afb6d3 --- /dev/null +++ b/lib/symfony/mailer/Transport/Smtp/Stream/SocketStream.php @@ -0,0 +1,193 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport\Smtp\Stream; + +use Symfony\Component\Mailer\Exception\TransportException; + +/** + * A stream supporting remote sockets. + * + * @author Fabien Potencier + * @author Chris Corbyn + * + * @internal + */ +final class SocketStream extends AbstractStream +{ + private string $url; + private string $host = 'localhost'; + private int $port = 465; + private float $timeout; + private bool $tls = true; + private ?string $sourceIp = null; + private array $streamContextOptions = []; + + /** + * @return $this + */ + public function setTimeout(float $timeout): static + { + $this->timeout = $timeout; + + return $this; + } + + public function getTimeout(): float + { + return $this->timeout ?? (float) \ini_get('default_socket_timeout'); + } + + /** + * Literal IPv6 addresses should be wrapped in square brackets. + * + * @return $this + */ + public function setHost(string $host): static + { + $this->host = $host; + + return $this; + } + + public function getHost(): string + { + return $this->host; + } + + /** + * @return $this + */ + public function setPort(int $port): static + { + $this->port = $port; + + return $this; + } + + public function getPort(): int + { + return $this->port; + } + + /** + * Sets the TLS/SSL on the socket (disables STARTTLS). + * + * @return $this + */ + public function disableTls(): static + { + $this->tls = false; + + return $this; + } + + public function isTLS(): bool + { + return $this->tls; + } + + /** + * @return $this + */ + public function setStreamOptions(array $options): static + { + $this->streamContextOptions = $options; + + return $this; + } + + public function getStreamOptions(): array + { + return $this->streamContextOptions; + } + + /** + * Sets the source IP. + * + * IPv6 addresses should be wrapped in square brackets. + * + * @return $this + */ + public function setSourceIp(string $ip): static + { + $this->sourceIp = $ip; + + return $this; + } + + /** + * Returns the IP used to connect to the destination. + */ + public function getSourceIp(): ?string + { + return $this->sourceIp; + } + + public function initialize(): void + { + $this->url = $this->host.':'.$this->port; + if ($this->tls) { + $this->url = 'ssl://'.$this->url; + } + $options = []; + if ($this->sourceIp) { + $options['socket']['bindto'] = $this->sourceIp.':0'; + } + if ($this->streamContextOptions) { + $options = array_merge($options, $this->streamContextOptions); + } + // do it unconditionally as it will be used by STARTTLS as well if supported + $options['ssl']['crypto_method'] ??= \STREAM_CRYPTO_METHOD_TLS_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; + $streamContext = stream_context_create($options); + + $timeout = $this->getTimeout(); + set_error_handler(function ($type, $msg) { + throw new TransportException(\sprintf('Connection could not be established with host "%s": ', $this->url).$msg); + }); + try { + $this->stream = stream_socket_client($this->url, $errno, $errstr, $timeout, \STREAM_CLIENT_CONNECT, $streamContext); + } finally { + restore_error_handler(); + } + + stream_set_blocking($this->stream, true); + stream_set_timeout($this->stream, (int) $timeout, (int) (($timeout - (int) $timeout) * 1000000)); + $this->in = &$this->stream; + $this->out = &$this->stream; + } + + public function startTLS(): bool + { + set_error_handler(function ($type, $msg) { + throw new TransportException('Unable to connect with STARTTLS: '.$msg); + }); + try { + return stream_socket_enable_crypto($this->stream, true); + } finally { + restore_error_handler(); + } + } + + public function terminate(): void + { + if (null !== $this->stream) { + fclose($this->stream); + } + + parent::terminate(); + } + + protected function getReadConnectionDescription(): string + { + return $this->url; + } +} diff --git a/lib/symfony/mailer/Transport/TransportFactoryInterface.php b/lib/symfony/mailer/Transport/TransportFactoryInterface.php new file mode 100644 index 000000000..9785ae81a --- /dev/null +++ b/lib/symfony/mailer/Transport/TransportFactoryInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Exception\IncompleteDsnException; +use Symfony\Component\Mailer\Exception\UnsupportedSchemeException; + +/** + * @author Konstantin Myakshin + */ +interface TransportFactoryInterface +{ + /** + * @throws UnsupportedSchemeException + * @throws IncompleteDsnException + */ + public function create(Dsn $dsn): TransportInterface; + + public function supports(Dsn $dsn): bool; +} diff --git a/lib/symfony/mailer/Transport/TransportInterface.php b/lib/symfony/mailer/Transport/TransportInterface.php new file mode 100644 index 000000000..01570cab4 --- /dev/null +++ b/lib/symfony/mailer/Transport/TransportInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\RawMessage; + +/** + * Interface for all mailer transports. + * + * When sending emails, you should prefer MailerInterface implementations + * as they allow asynchronous sending. + * + * @author Fabien Potencier + */ +interface TransportInterface extends \Stringable +{ + /** + * @throws TransportExceptionInterface + */ + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage; +} diff --git a/lib/symfony/mailer/Transport/Transports.php b/lib/symfony/mailer/Transport/Transports.php new file mode 100644 index 000000000..1d97ea68e --- /dev/null +++ b/lib/symfony/mailer/Transport/Transports.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Transport; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\InvalidArgumentException; +use Symfony\Component\Mailer\Exception\LogicException; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +/** + * @author Fabien Potencier + */ +final class Transports implements TransportInterface +{ + /** + * @var array + */ + private array $transports = []; + private TransportInterface $default; + + /** + * @param iterable $transports + */ + public function __construct(iterable $transports) + { + foreach ($transports as $name => $transport) { + $this->default ??= $transport; + $this->transports[$name] = $transport; + } + + if (!$this->transports) { + throw new LogicException(\sprintf('"%s" must have at least one transport configured.', __CLASS__)); + } + } + + public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage + { + /** @var Message $message */ + if (RawMessage::class === $message::class || !$message->getHeaders()->has('X-Transport')) { + return $this->default->send($message, $envelope); + } + + $headers = $message->getHeaders(); + $transport = $headers->get('X-Transport')->getBody(); + $headers->remove('X-Transport'); + + if (!isset($this->transports[$transport])) { + throw new InvalidArgumentException(\sprintf('The "%s" transport does not exist (available transports: "%s").', $transport, implode('", "', array_keys($this->transports)))); + } + + try { + return $this->transports[$transport]->send($message, $envelope); + } catch (\Throwable $e) { + $headers->addTextHeader('X-Transport', $transport); + + throw $e; + } + } + + public function __toString(): string + { + return '['.implode(',', array_keys($this->transports)).']'; + } +} diff --git a/lib/symfony/mailer/composer.json b/lib/symfony/mailer/composer.json new file mode 100644 index 000000000..28dcb9196 --- /dev/null +++ b/lib/symfony/mailer/composer.json @@ -0,0 +1,47 @@ +{ + "name": "symfony/mailer", + "type": "library", + "description": "Helps sending emails", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.1", + "egulias/email-validator": "^2.1.10|^3|^4", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.2|^7.0", + "symfony/twig-bridge": "^6.2|^7.0" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/messenger": "<6.2", + "symfony/mime": "<6.2", + "symfony/twig-bridge": "<6.2.1" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Mailer\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/lib/symfony/mime/Address.php b/lib/symfony/mime/Address.php new file mode 100644 index 000000000..a78b64321 --- /dev/null +++ b/lib/symfony/mime/Address.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Egulias\EmailValidator\EmailValidator; +use Egulias\EmailValidator\Validation\MessageIDValidation; +use Egulias\EmailValidator\Validation\RFCValidation; +use Symfony\Component\Mime\Encoder\IdnAddressEncoder; +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Exception\LogicException; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * @author Fabien Potencier + */ +final class Address +{ + /** + * A regex that matches a structure like 'Name '. + * It matches anything between the first < and last > as email address. + * This allows to use a single string to construct an Address, which can be convenient to use in + * config, and allows to have more readable config. + * This does not try to cover all edge cases for address. + */ + private const FROM_STRING_PATTERN = '~(?[^<]*)<(?.*)>[^>]*~'; + + private static EmailValidator $validator; + private static IdnAddressEncoder $encoder; + + private string $address; + private string $name; + + public function __construct(string $address, string $name = '') + { + if (!class_exists(EmailValidator::class)) { + throw new LogicException(\sprintf('The "%s" class cannot be used as it needs "%s". Try running "composer require egulias/email-validator".', __CLASS__, EmailValidator::class)); + } + + self::$validator ??= new EmailValidator(); + + $this->address = trim($address); + $this->name = trim(str_replace(["\n", "\r"], '', $name)); + + if (!self::$validator->isValid($this->address, class_exists(MessageIDValidation::class) ? new MessageIDValidation() : new RFCValidation())) { + throw new RfcComplianceException(\sprintf('Email "%s" does not comply with addr-spec of RFC 2822.', $address)); + } + } + + public function getAddress(): string + { + return $this->address; + } + + public function getName(): string + { + return $this->name; + } + + public function getEncodedAddress(): string + { + self::$encoder ??= new IdnAddressEncoder(); + + return self::$encoder->encodeString($this->address); + } + + public function toString(): string + { + return ($n = $this->getEncodedName()) ? $n.' <'.$this->getEncodedAddress().'>' : $this->getEncodedAddress(); + } + + public function getEncodedName(): string + { + if ('' === $this->getName()) { + return ''; + } + + return \sprintf('"%s"', preg_replace('/"/u', '\"', $this->getName())); + } + + public static function create(self|string $address): self + { + if ($address instanceof self) { + return $address; + } + + if (!str_contains($address, '<')) { + return new self($address); + } + + if (!preg_match(self::FROM_STRING_PATTERN, $address, $matches)) { + throw new InvalidArgumentException(\sprintf('Could not parse "%s" to a "%s" instance.', $address, self::class)); + } + + return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"')); + } + + /** + * @param array $addresses + * + * @return Address[] + */ + public static function createArray(array $addresses): array + { + $addrs = []; + foreach ($addresses as $address) { + $addrs[] = self::create($address); + } + + return $addrs; + } +} diff --git a/lib/symfony/mime/BodyRendererInterface.php b/lib/symfony/mime/BodyRendererInterface.php new file mode 100644 index 000000000..d69217265 --- /dev/null +++ b/lib/symfony/mime/BodyRendererInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +/** + * @author Fabien Potencier + */ +interface BodyRendererInterface +{ + public function render(Message $message): void; +} diff --git a/lib/symfony/mime/CHANGELOG.md b/lib/symfony/mime/CHANGELOG.md new file mode 100644 index 000000000..41eb14a4e --- /dev/null +++ b/lib/symfony/mime/CHANGELOG.md @@ -0,0 +1,50 @@ +CHANGELOG +========= + +6.3 +--- + + * Support detection of related parts if `Content-Id` is used instead of the name + * Add `TextPart::getDisposition()` + +6.2 +--- + + * Add `File` + * Deprecate `Email::attachPart()`, use `addPart()` instead + * Deprecate calling `Message::setBody()` without arguments + +6.1 +--- + + * Add `DataPart::getFilename()` and `DataPart::getContentType()` + +6.0 +--- + + * Remove `Address::fromString()`, use `Address::create()` instead + * Remove `Serializable` interface from `RawMessage` + +5.2.0 +----- + + * Add support for DKIM + * Deprecated `Address::fromString()`, use `Address::create()` instead + +4.4.0 +----- + + * [BC BREAK] Removed `NamedAddress` (`Address` now supports a name) + * Added PHPUnit constraints + * Added `AbstractPart::asDebugString()` + * Added `Address::fromString()` + +4.3.3 +----- + + * [BC BREAK] Renamed method `Headers::getAll()` to `Headers::all()`. + +4.3.0 +----- + + * Introduced the component as experimental diff --git a/lib/symfony/mime/CharacterStream.php b/lib/symfony/mime/CharacterStream.php new file mode 100644 index 000000000..21d7bc5f0 --- /dev/null +++ b/lib/symfony/mime/CharacterStream.php @@ -0,0 +1,211 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +/** + * @author Fabien Potencier + * @author Xavier De Cock + * + * @internal + */ +final class CharacterStream +{ + /** Pre-computed for optimization */ + private const UTF8_LENGTH_MAP = [ + "\x00" => 1, "\x01" => 1, "\x02" => 1, "\x03" => 1, "\x04" => 1, "\x05" => 1, "\x06" => 1, "\x07" => 1, + "\x08" => 1, "\x09" => 1, "\x0a" => 1, "\x0b" => 1, "\x0c" => 1, "\x0d" => 1, "\x0e" => 1, "\x0f" => 1, + "\x10" => 1, "\x11" => 1, "\x12" => 1, "\x13" => 1, "\x14" => 1, "\x15" => 1, "\x16" => 1, "\x17" => 1, + "\x18" => 1, "\x19" => 1, "\x1a" => 1, "\x1b" => 1, "\x1c" => 1, "\x1d" => 1, "\x1e" => 1, "\x1f" => 1, + "\x20" => 1, "\x21" => 1, "\x22" => 1, "\x23" => 1, "\x24" => 1, "\x25" => 1, "\x26" => 1, "\x27" => 1, + "\x28" => 1, "\x29" => 1, "\x2a" => 1, "\x2b" => 1, "\x2c" => 1, "\x2d" => 1, "\x2e" => 1, "\x2f" => 1, + "\x30" => 1, "\x31" => 1, "\x32" => 1, "\x33" => 1, "\x34" => 1, "\x35" => 1, "\x36" => 1, "\x37" => 1, + "\x38" => 1, "\x39" => 1, "\x3a" => 1, "\x3b" => 1, "\x3c" => 1, "\x3d" => 1, "\x3e" => 1, "\x3f" => 1, + "\x40" => 1, "\x41" => 1, "\x42" => 1, "\x43" => 1, "\x44" => 1, "\x45" => 1, "\x46" => 1, "\x47" => 1, + "\x48" => 1, "\x49" => 1, "\x4a" => 1, "\x4b" => 1, "\x4c" => 1, "\x4d" => 1, "\x4e" => 1, "\x4f" => 1, + "\x50" => 1, "\x51" => 1, "\x52" => 1, "\x53" => 1, "\x54" => 1, "\x55" => 1, "\x56" => 1, "\x57" => 1, + "\x58" => 1, "\x59" => 1, "\x5a" => 1, "\x5b" => 1, "\x5c" => 1, "\x5d" => 1, "\x5e" => 1, "\x5f" => 1, + "\x60" => 1, "\x61" => 1, "\x62" => 1, "\x63" => 1, "\x64" => 1, "\x65" => 1, "\x66" => 1, "\x67" => 1, + "\x68" => 1, "\x69" => 1, "\x6a" => 1, "\x6b" => 1, "\x6c" => 1, "\x6d" => 1, "\x6e" => 1, "\x6f" => 1, + "\x70" => 1, "\x71" => 1, "\x72" => 1, "\x73" => 1, "\x74" => 1, "\x75" => 1, "\x76" => 1, "\x77" => 1, + "\x78" => 1, "\x79" => 1, "\x7a" => 1, "\x7b" => 1, "\x7c" => 1, "\x7d" => 1, "\x7e" => 1, "\x7f" => 1, + "\x80" => 0, "\x81" => 0, "\x82" => 0, "\x83" => 0, "\x84" => 0, "\x85" => 0, "\x86" => 0, "\x87" => 0, + "\x88" => 0, "\x89" => 0, "\x8a" => 0, "\x8b" => 0, "\x8c" => 0, "\x8d" => 0, "\x8e" => 0, "\x8f" => 0, + "\x90" => 0, "\x91" => 0, "\x92" => 0, "\x93" => 0, "\x94" => 0, "\x95" => 0, "\x96" => 0, "\x97" => 0, + "\x98" => 0, "\x99" => 0, "\x9a" => 0, "\x9b" => 0, "\x9c" => 0, "\x9d" => 0, "\x9e" => 0, "\x9f" => 0, + "\xa0" => 0, "\xa1" => 0, "\xa2" => 0, "\xa3" => 0, "\xa4" => 0, "\xa5" => 0, "\xa6" => 0, "\xa7" => 0, + "\xa8" => 0, "\xa9" => 0, "\xaa" => 0, "\xab" => 0, "\xac" => 0, "\xad" => 0, "\xae" => 0, "\xaf" => 0, + "\xb0" => 0, "\xb1" => 0, "\xb2" => 0, "\xb3" => 0, "\xb4" => 0, "\xb5" => 0, "\xb6" => 0, "\xb7" => 0, + "\xb8" => 0, "\xb9" => 0, "\xba" => 0, "\xbb" => 0, "\xbc" => 0, "\xbd" => 0, "\xbe" => 0, "\xbf" => 0, + "\xc0" => 2, "\xc1" => 2, "\xc2" => 2, "\xc3" => 2, "\xc4" => 2, "\xc5" => 2, "\xc6" => 2, "\xc7" => 2, + "\xc8" => 2, "\xc9" => 2, "\xca" => 2, "\xcb" => 2, "\xcc" => 2, "\xcd" => 2, "\xce" => 2, "\xcf" => 2, + "\xd0" => 2, "\xd1" => 2, "\xd2" => 2, "\xd3" => 2, "\xd4" => 2, "\xd5" => 2, "\xd6" => 2, "\xd7" => 2, + "\xd8" => 2, "\xd9" => 2, "\xda" => 2, "\xdb" => 2, "\xdc" => 2, "\xdd" => 2, "\xde" => 2, "\xdf" => 2, + "\xe0" => 3, "\xe1" => 3, "\xe2" => 3, "\xe3" => 3, "\xe4" => 3, "\xe5" => 3, "\xe6" => 3, "\xe7" => 3, + "\xe8" => 3, "\xe9" => 3, "\xea" => 3, "\xeb" => 3, "\xec" => 3, "\xed" => 3, "\xee" => 3, "\xef" => 3, + "\xf0" => 4, "\xf1" => 4, "\xf2" => 4, "\xf3" => 4, "\xf4" => 4, "\xf5" => 4, "\xf6" => 4, "\xf7" => 4, + "\xf8" => 5, "\xf9" => 5, "\xfa" => 5, "\xfb" => 5, "\xfc" => 6, "\xfd" => 6, "\xfe" => 0, "\xff" => 0, + ]; + + private string $data = ''; + private int $dataSize = 0; + private array $map = []; + private int $charCount = 0; + private int $currentPos = 0; + private int $fixedWidth = 0; + + /** + * @param resource|string $input + */ + public function __construct($input, ?string $charset = 'utf-8') + { + $charset = strtolower(trim($charset)) ?: 'utf-8'; + if ('utf-8' === $charset || 'utf8' === $charset) { + $this->fixedWidth = 0; + $this->map = ['p' => [], 'i' => []]; + } else { + $this->fixedWidth = match ($charset) { + // 16 bits + 'ucs2', + 'ucs-2', + 'utf16', + 'utf-16' => 2, + // 32 bits + 'ucs4', + 'ucs-4', + 'utf32', + 'utf-32' => 4, + // 7-8 bit charsets: (us-)?ascii, (iso|iec)-?8859-?[0-9]+, windows-?125[0-9], cp-?[0-9]+, ansi, macintosh, + // koi-?7, koi-?8-?.+, mik, (cork|t1), v?iscii + // and fallback + default => 1, + }; + } + if (\is_resource($input)) { + $blocks = 16372; + while (false !== $read = fread($input, $blocks)) { + $this->write($read); + } + } else { + $this->write($input); + } + } + + public function read(int $length): ?string + { + if ($this->currentPos >= $this->charCount) { + return null; + } + $length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length; + if ($this->fixedWidth > 0) { + $len = $length * $this->fixedWidth; + $ret = substr($this->data, $this->currentPos * $this->fixedWidth, $len); + $this->currentPos += $length; + } else { + $end = $this->currentPos + $length; + $end = $end > $this->charCount ? $this->charCount : $end; + $ret = ''; + $start = 0; + if ($this->currentPos > 0) { + $start = $this->map['p'][$this->currentPos - 1]; + } + $to = $start; + for (; $this->currentPos < $end; ++$this->currentPos) { + if (isset($this->map['i'][$this->currentPos])) { + $ret .= substr($this->data, $start, $to - $start).'?'; + $start = $this->map['p'][$this->currentPos]; + } else { + $to = $this->map['p'][$this->currentPos]; + } + } + $ret .= substr($this->data, $start, $to - $start); + } + + return $ret; + } + + public function readBytes(int $length): ?array + { + if (null !== $read = $this->read($length)) { + return array_map('ord', str_split($read, 1)); + } + + return null; + } + + public function setPointer(int $charOffset): void + { + if ($this->charCount < $charOffset) { + $charOffset = $this->charCount; + } + $this->currentPos = $charOffset; + } + + public function write(string $chars): void + { + $ignored = ''; + $this->data .= $chars; + if ($this->fixedWidth > 0) { + $strlen = \strlen($chars); + $ignoredL = $strlen % $this->fixedWidth; + $ignored = $ignoredL ? substr($chars, -$ignoredL) : ''; + $this->charCount += ($strlen - $ignoredL) / $this->fixedWidth; + } else { + $this->charCount += $this->getUtf8CharPositions($chars, $this->dataSize, $ignored); + } + $this->dataSize = \strlen($this->data) - \strlen($ignored); + } + + private function getUtf8CharPositions(string $string, int $startOffset, string &$ignoredChars): int + { + $strlen = \strlen($string); + $charPos = \count($this->map['p']); + $foundChars = 0; + $invalid = false; + for ($i = 0; $i < $strlen; ++$i) { + $char = $string[$i]; + $size = self::UTF8_LENGTH_MAP[$char]; + if (0 == $size) { + /* char is invalid, we must wait for a resync */ + $invalid = true; + continue; + } + + if ($invalid) { + /* We mark the chars as invalid and start a new char */ + $this->map['p'][$charPos + $foundChars] = $startOffset + $i; + $this->map['i'][$charPos + $foundChars] = true; + ++$foundChars; + $invalid = false; + } + if (($i + $size) > $strlen) { + $ignoredChars = substr($string, $i); + break; + } + for ($j = 1; $j < $size; ++$j) { + $char = $string[$i + $j]; + if ($char > "\x7F" && $char < "\xC0") { + // Valid - continue parsing + } else { + /* char is invalid, we must wait for a resync */ + $invalid = true; + continue 2; + } + } + /* Ok we got a complete char here */ + $this->map['p'][$charPos + $foundChars] = $startOffset + $i + $size; + $i += $j - 1; + ++$foundChars; + } + + return $foundChars; + } +} diff --git a/lib/symfony/mime/Crypto/DkimOptions.php b/lib/symfony/mime/Crypto/DkimOptions.php new file mode 100644 index 000000000..cee4e7cb8 --- /dev/null +++ b/lib/symfony/mime/Crypto/DkimOptions.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +/** + * A helper providing autocompletion for available DkimSigner options. + * + * @author Fabien Potencier + */ +final class DkimOptions +{ + private array $options = []; + + public function toArray(): array + { + return $this->options; + } + + /** + * @return $this + */ + public function algorithm(string $algo): static + { + $this->options['algorithm'] = $algo; + + return $this; + } + + /** + * @return $this + */ + public function signatureExpirationDelay(int $show): static + { + $this->options['signature_expiration_delay'] = $show; + + return $this; + } + + /** + * @return $this + */ + public function bodyMaxLength(int $max): static + { + $this->options['body_max_length'] = $max; + + return $this; + } + + /** + * @return $this + */ + public function bodyShowLength(bool $show): static + { + $this->options['body_show_length'] = $show; + + return $this; + } + + /** + * @return $this + */ + public function headerCanon(string $canon): static + { + $this->options['header_canon'] = $canon; + + return $this; + } + + /** + * @return $this + */ + public function bodyCanon(string $canon): static + { + $this->options['body_canon'] = $canon; + + return $this; + } + + /** + * @return $this + */ + public function headersToIgnore(array $headers): static + { + $this->options['headers_to_ignore'] = $headers; + + return $this; + } +} diff --git a/lib/symfony/mime/Crypto/DkimSigner.php b/lib/symfony/mime/Crypto/DkimSigner.php new file mode 100644 index 000000000..2ef0ac519 --- /dev/null +++ b/lib/symfony/mime/Crypto/DkimSigner.php @@ -0,0 +1,217 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Header\UnstructuredHeader; +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\Part\AbstractPart; + +/** + * @author Fabien Potencier + * + * RFC 6376 and 8301 + */ +final class DkimSigner +{ + public const CANON_SIMPLE = 'simple'; + public const CANON_RELAXED = 'relaxed'; + + public const ALGO_SHA256 = 'rsa-sha256'; + public const ALGO_ED25519 = 'ed25519-sha256'; // RFC 8463 + + private \OpenSSLAsymmetricKey $key; + private string $domainName; + private string $selector; + private array $defaultOptions; + + /** + * @param string $pk The private key as a string or the path to the file containing the private key, should be prefixed with file:// (in PEM format) + * @param string $passphrase A passphrase of the private key (if any) + */ + public function __construct(string $pk, string $domainName, string $selector, array $defaultOptions = [], string $passphrase = '') + { + if (!\extension_loaded('openssl')) { + throw new \LogicException('PHP extension "openssl" is required to use DKIM.'); + } + $this->key = openssl_pkey_get_private($pk, $passphrase) ?: throw new InvalidArgumentException('Unable to load DKIM private key: '.openssl_error_string()); + $this->domainName = $domainName; + $this->selector = $selector; + $this->defaultOptions = $defaultOptions + [ + 'algorithm' => self::ALGO_SHA256, + 'signature_expiration_delay' => 0, + 'body_max_length' => \PHP_INT_MAX, + 'body_show_length' => false, + 'header_canon' => self::CANON_RELAXED, + 'body_canon' => self::CANON_RELAXED, + 'headers_to_ignore' => [], + ]; + } + + public function sign(Message $message, array $options = []): Message + { + $options += $this->defaultOptions; + if (!\in_array($options['algorithm'], [self::ALGO_SHA256, self::ALGO_ED25519], true)) { + throw new InvalidArgumentException(\sprintf('Invalid DKIM signing algorithm "%s".', $options['algorithm'])); + } + $headersToIgnore['return-path'] = true; + $headersToIgnore['x-transport'] = true; + foreach ($options['headers_to_ignore'] as $name) { + $headersToIgnore[strtolower($name)] = true; + } + unset($headersToIgnore['from']); + $signedHeaderNames = []; + $headerCanonData = ''; + $headers = $message->getPreparedHeaders(); + foreach ($headers->getNames() as $name) { + foreach ($headers->all($name) as $header) { + if (isset($headersToIgnore[strtolower($header->getName())])) { + continue; + } + + if ('' !== $header->getBodyAsString()) { + $headerCanonData .= $this->canonicalizeHeader($header->toString(), $options['header_canon']); + $signedHeaderNames[] = $header->getName(); + } + } + } + + [$bodyHash, $bodyLength] = $this->hashBody($message->getBody(), $options['body_canon'], $options['body_max_length']); + + $params = [ + 'v' => '1', + 'q' => 'dns/txt', + 'a' => $options['algorithm'], + 'bh' => base64_encode($bodyHash), + 'd' => $this->domainName, + 'h' => implode(': ', $signedHeaderNames), + 'i' => '@'.$this->domainName, + 's' => $this->selector, + 't' => time(), + 'c' => $options['header_canon'].'/'.$options['body_canon'], + ]; + + if ($options['body_show_length']) { + $params['l'] = $bodyLength; + } + if ($options['signature_expiration_delay']) { + $params['x'] = $params['t'] + $options['signature_expiration_delay']; + } + $value = ''; + foreach ($params as $k => $v) { + $value .= $k.'='.$v.'; '; + } + $value = trim($value); + $header = new UnstructuredHeader('DKIM-Signature', $value); + $headerCanonData .= rtrim($this->canonicalizeHeader($header->toString()."\r\n b=", $options['header_canon'])); + if (self::ALGO_SHA256 === $options['algorithm']) { + if (!openssl_sign($headerCanonData, $signature, $this->key, \OPENSSL_ALGO_SHA256)) { + throw new RuntimeException('Unable to sign DKIM hash: '.openssl_error_string()); + } + } else { + throw new \RuntimeException(\sprintf('The "%s" DKIM signing algorithm is not supported yet.', self::ALGO_ED25519)); + } + $header->setValue($value.' b='.trim(chunk_split(base64_encode($signature), 73, ' '))); + $headers->add($header); + + return new Message($headers, $message->getBody()); + } + + private function canonicalizeHeader(string $header, string $headerCanon): string + { + if (self::CANON_RELAXED !== $headerCanon) { + return $header."\r\n"; + } + + $exploded = explode(':', $header, 2); + $name = strtolower(trim($exploded[0])); + $value = str_replace("\r\n", '', $exploded[1]); + $value = trim(preg_replace("/[ \t][ \t]+/", ' ', $value)); + + return $name.':'.$value."\r\n"; + } + + private function hashBody(AbstractPart $body, string $bodyCanon, int $maxLength): array + { + $hash = hash_init('sha256'); + $relaxed = self::CANON_RELAXED === $bodyCanon; + $currentLine = ''; + $emptyCounter = 0; + $isSpaceSequence = false; + $length = 0; + foreach ($body->bodyToIterable() as $chunk) { + $canon = ''; + for ($i = 0, $len = \strlen($chunk); $i < $len; ++$i) { + switch ($chunk[$i]) { + case "\r": + break; + case "\n": + // previous char is always \r + if ($relaxed) { + $isSpaceSequence = false; + } + if ('' === $currentLine) { + ++$emptyCounter; + } else { + $currentLine = ''; + $canon .= "\r\n"; + } + break; + case ' ': + case "\t": + if ($relaxed) { + $isSpaceSequence = true; + break; + } + // no break + default: + if ($emptyCounter > 0) { + $canon .= str_repeat("\r\n", $emptyCounter); + $emptyCounter = 0; + } + if ($isSpaceSequence) { + $currentLine .= ' '; + $canon .= ' '; + $isSpaceSequence = false; + } + $currentLine .= $chunk[$i]; + $canon .= $chunk[$i]; + } + } + + if ($length + \strlen($canon) >= $maxLength) { + $canon = substr($canon, 0, $maxLength - $length); + $length += \strlen($canon); + hash_update($hash, $canon); + + break; + } + + $length += \strlen($canon); + hash_update($hash, $canon); + } + + // Add trailing Line return if last line is non empty + if ('' !== $currentLine) { + hash_update($hash, "\r\n"); + $length += \strlen("\r\n"); + } + + if (!$relaxed && 0 === $length) { + hash_update($hash, "\r\n"); + $length = 2; + } + + return [hash_final($hash, true), $length]; + } +} diff --git a/lib/symfony/mime/Crypto/SMime.php b/lib/symfony/mime/Crypto/SMime.php new file mode 100644 index 000000000..f72ba010c --- /dev/null +++ b/lib/symfony/mime/Crypto/SMime.php @@ -0,0 +1,111 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Part\SMimePart; + +/** + * @author Sebastiaan Stok + * + * @internal + */ +abstract class SMime +{ + protected function normalizeFilePath(string $path): string + { + if (!file_exists($path)) { + throw new RuntimeException(\sprintf('File does not exist: "%s".', $path)); + } + + return 'file://'.str_replace('\\', '/', realpath($path)); + } + + protected function iteratorToFile(iterable $iterator, $stream): void + { + foreach ($iterator as $chunk) { + fwrite($stream, $chunk); + } + } + + protected function convertMessageToSMimePart($stream, string $type, string $subtype): SMimePart + { + rewind($stream); + + $headers = ''; + + while (!feof($stream)) { + $buffer = fread($stream, 78); + $headers .= $buffer; + + // Detect ending of header list + if (preg_match('/(\r\n\r\n|\n\n)/', $headers, $match)) { + $headersPosEnd = strpos($headers, $headerBodySeparator = $match[0]); + + break; + } + } + + $headers = $this->getMessageHeaders(trim(substr($headers, 0, $headersPosEnd))); + + fseek($stream, $headersPosEnd + \strlen($headerBodySeparator)); + + return new SMimePart($this->getStreamIterator($stream), $type, $subtype, $this->getParametersFromHeader($headers['content-type'])); + } + + protected function getStreamIterator($stream): iterable + { + while (!feof($stream)) { + yield str_replace("\n", "\r\n", str_replace("\r\n", "\n", fread($stream, 16372))); + } + } + + private function getMessageHeaders(string $headerData): array + { + $headers = []; + $headerLines = explode("\r\n", str_replace("\n", "\r\n", str_replace("\r\n", "\n", $headerData))); + $currentHeaderName = ''; + + // Transform header lines into an associative array + foreach ($headerLines as $headerLine) { + // Empty lines between headers indicate a new mime-entity + if ('' === $headerLine) { + break; + } + + // Handle headers that span multiple lines + if (!str_contains($headerLine, ':')) { + $headers[$currentHeaderName] .= ' '.trim($headerLine); + continue; + } + + $header = explode(':', $headerLine, 2); + $currentHeaderName = strtolower($header[0]); + $headers[$currentHeaderName] = trim($header[1]); + } + + return $headers; + } + + private function getParametersFromHeader(string $header): array + { + $params = []; + + preg_match_all('/(?P[a-z-0-9]+)=(?P"[^"]+"|(?:[^\s;]+|$))(?:\s+;)?/i', $header, $matches); + + foreach ($matches['value'] as $pos => $paramValue) { + $params[$matches['name'][$pos]] = trim($paramValue, '"'); + } + + return $params; + } +} diff --git a/lib/symfony/mime/Crypto/SMimeEncrypter.php b/lib/symfony/mime/Crypto/SMimeEncrypter.php new file mode 100644 index 000000000..d7c0af68b --- /dev/null +++ b/lib/symfony/mime/Crypto/SMimeEncrypter.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Message; + +/** + * @author Sebastiaan Stok + */ +final class SMimeEncrypter extends SMime +{ + private string|array $certs; + private int $cipher; + + /** + * @param string|string[] $certificate The path (or array of paths) of the file(s) containing the X.509 certificate(s) + * @param int|null $cipher A set of algorithms used to encrypt the message. Must be one of these PHP constants: https://php.net/openssl.ciphers + */ + public function __construct(string|array $certificate, ?int $cipher = null) + { + if (!\extension_loaded('openssl')) { + throw new \LogicException('PHP extension "openssl" is required to use SMime.'); + } + + if (\is_array($certificate)) { + $this->certs = array_map($this->normalizeFilePath(...), $certificate); + } else { + $this->certs = $this->normalizeFilePath($certificate); + } + + $this->cipher = $cipher ?? \OPENSSL_CIPHER_AES_256_CBC; + } + + public function encrypt(Message $message): Message + { + $bufferFile = tmpfile(); + $outputFile = tmpfile(); + + $this->iteratorToFile($message->toIterable(), $bufferFile); + + if (!@openssl_pkcs7_encrypt(stream_get_meta_data($bufferFile)['uri'], stream_get_meta_data($outputFile)['uri'], $this->certs, [], 0, $this->cipher)) { + throw new RuntimeException(\sprintf('Failed to encrypt S/Mime message. Error: "%s".', openssl_error_string())); + } + + $mimePart = $this->convertMessageToSMimePart($outputFile, 'application', 'pkcs7-mime'); + $mimePart->getHeaders() + ->addTextHeader('Content-Transfer-Encoding', 'base64') + ->addParameterizedHeader('Content-Disposition', 'attachment', ['name' => 'smime.p7m']) + ; + + return new Message($message->getHeaders(), $mimePart); + } +} diff --git a/lib/symfony/mime/Crypto/SMimeSigner.php b/lib/symfony/mime/Crypto/SMimeSigner.php new file mode 100644 index 000000000..d17e17754 --- /dev/null +++ b/lib/symfony/mime/Crypto/SMimeSigner.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Crypto; + +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Message; + +/** + * @author Sebastiaan Stok + */ +final class SMimeSigner extends SMime +{ + private string $signCertificate; + private string|array $signPrivateKey; + private int $signOptions; + private ?string $extraCerts; + + /** + * @param string $certificate The path of the file containing the signing certificate (in PEM format) + * @param string $privateKey The path of the file containing the private key (in PEM format) + * @param string|null $privateKeyPassphrase A passphrase of the private key (if any) + * @param string|null $extraCerts The path of the file containing intermediate certificates (in PEM format) needed by the signing certificate + * @param int|null $signOptions Bitwise operator options for openssl_pkcs7_sign() (@see https://secure.php.net/manual/en/openssl.pkcs7.flags.php) + */ + public function __construct(string $certificate, string $privateKey, ?string $privateKeyPassphrase = null, ?string $extraCerts = null, ?int $signOptions = null) + { + if (!\extension_loaded('openssl')) { + throw new \LogicException('PHP extension "openssl" is required to use SMime.'); + } + + $this->signCertificate = $this->normalizeFilePath($certificate); + + if (null !== $privateKeyPassphrase) { + $this->signPrivateKey = [$this->normalizeFilePath($privateKey), $privateKeyPassphrase]; + } else { + $this->signPrivateKey = $this->normalizeFilePath($privateKey); + } + + $this->signOptions = $signOptions ?? \PKCS7_DETACHED; + $this->extraCerts = $extraCerts ? realpath($extraCerts) : null; + } + + public function sign(Message $message): Message + { + $bufferFile = tmpfile(); + $outputFile = tmpfile(); + + $this->iteratorToFile($message->getBody()->toIterable(), $bufferFile); + + if (!@openssl_pkcs7_sign(stream_get_meta_data($bufferFile)['uri'], stream_get_meta_data($outputFile)['uri'], $this->signCertificate, $this->signPrivateKey, [], $this->signOptions, $this->extraCerts)) { + throw new RuntimeException(\sprintf('Failed to sign S/Mime message. Error: "%s".', openssl_error_string())); + } + + return new Message($message->getHeaders(), $this->convertMessageToSMimePart($outputFile, 'multipart', 'signed')); + } +} diff --git a/lib/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php b/lib/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php new file mode 100644 index 000000000..70fa78633 --- /dev/null +++ b/lib/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Registers custom mime types guessers. + * + * @author Fabien Potencier + */ +class AddMimeTypeGuesserPass implements CompilerPassInterface +{ + /** + * @return void + */ + public function process(ContainerBuilder $container) + { + if ($container->has('mime_types')) { + $definition = $container->findDefinition('mime_types'); + foreach ($container->findTaggedServiceIds('mime.mime_type_guesser', true) as $id => $attributes) { + $definition->addMethodCall('registerGuesser', [new Reference($id)]); + } + } + } +} diff --git a/lib/symfony/mime/DraftEmail.php b/lib/symfony/mime/DraftEmail.php new file mode 100644 index 000000000..82ce76369 --- /dev/null +++ b/lib/symfony/mime/DraftEmail.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Header\Headers; +use Symfony\Component\Mime\Part\AbstractPart; + +/** + * @author Kevin Bond + */ +class DraftEmail extends Email +{ + public function __construct(?Headers $headers = null, ?AbstractPart $body = null) + { + parent::__construct($headers, $body); + + $this->getHeaders()->addTextHeader('X-Unsent', '1'); + } + + /** + * Override default behavior as draft emails do not require From/Sender/Date/Message-ID headers. + * These are added by the client that actually sends the email. + */ + public function getPreparedHeaders(): Headers + { + $headers = clone $this->getHeaders(); + + if (!$headers->has('MIME-Version')) { + $headers->addTextHeader('MIME-Version', '1.0'); + } + + $headers->remove('Bcc'); + + return $headers; + } +} diff --git a/lib/symfony/mime/Email.php b/lib/symfony/mime/Email.php new file mode 100644 index 000000000..8183c7899 --- /dev/null +++ b/lib/symfony/mime/Email.php @@ -0,0 +1,591 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\LogicException; +use Symfony\Component\Mime\Part\AbstractPart; +use Symfony\Component\Mime\Part\DataPart; +use Symfony\Component\Mime\Part\File; +use Symfony\Component\Mime\Part\Multipart\AlternativePart; +use Symfony\Component\Mime\Part\Multipart\MixedPart; +use Symfony\Component\Mime\Part\Multipart\RelatedPart; +use Symfony\Component\Mime\Part\TextPart; + +/** + * @author Fabien Potencier + */ +class Email extends Message +{ + public const PRIORITY_HIGHEST = 1; + public const PRIORITY_HIGH = 2; + public const PRIORITY_NORMAL = 3; + public const PRIORITY_LOW = 4; + public const PRIORITY_LOWEST = 5; + + private const PRIORITY_MAP = [ + self::PRIORITY_HIGHEST => 'Highest', + self::PRIORITY_HIGH => 'High', + self::PRIORITY_NORMAL => 'Normal', + self::PRIORITY_LOW => 'Low', + self::PRIORITY_LOWEST => 'Lowest', + ]; + + /** + * @var resource|string|null + */ + private $text; + + private ?string $textCharset = null; + + /** + * @var resource|string|null + */ + private $html; + + private ?string $htmlCharset = null; + private array $attachments = []; + private ?AbstractPart $cachedBody = null; // Used to avoid wrong body hash in DKIM signatures with multiple parts (e.g. HTML + TEXT) due to multiple boundaries. + + /** + * @return $this + */ + public function subject(string $subject): static + { + return $this->setHeaderBody('Text', 'Subject', $subject); + } + + public function getSubject(): ?string + { + return $this->getHeaders()->getHeaderBody('Subject'); + } + + /** + * @return $this + */ + public function date(\DateTimeInterface $dateTime): static + { + return $this->setHeaderBody('Date', 'Date', $dateTime); + } + + public function getDate(): ?\DateTimeImmutable + { + return $this->getHeaders()->getHeaderBody('Date'); + } + + /** + * @return $this + */ + public function returnPath(Address|string $address): static + { + return $this->setHeaderBody('Path', 'Return-Path', Address::create($address)); + } + + public function getReturnPath(): ?Address + { + return $this->getHeaders()->getHeaderBody('Return-Path'); + } + + /** + * @return $this + */ + public function sender(Address|string $address): static + { + return $this->setHeaderBody('Mailbox', 'Sender', Address::create($address)); + } + + public function getSender(): ?Address + { + return $this->getHeaders()->getHeaderBody('Sender'); + } + + /** + * @return $this + */ + public function addFrom(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('From', $addresses); + } + + /** + * @return $this + */ + public function from(Address|string ...$addresses): static + { + if (!$addresses) { + throw new LogicException('"from()" must be called with at least one address.'); + } + + return $this->setListAddressHeaderBody('From', $addresses); + } + + /** + * @return Address[] + */ + public function getFrom(): array + { + return $this->getHeaders()->getHeaderBody('From') ?: []; + } + + /** + * @return $this + */ + public function addReplyTo(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('Reply-To', $addresses); + } + + /** + * @return $this + */ + public function replyTo(Address|string ...$addresses): static + { + return $this->setListAddressHeaderBody('Reply-To', $addresses); + } + + /** + * @return Address[] + */ + public function getReplyTo(): array + { + return $this->getHeaders()->getHeaderBody('Reply-To') ?: []; + } + + /** + * @return $this + */ + public function addTo(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('To', $addresses); + } + + /** + * @return $this + */ + public function to(Address|string ...$addresses): static + { + return $this->setListAddressHeaderBody('To', $addresses); + } + + /** + * @return Address[] + */ + public function getTo(): array + { + return $this->getHeaders()->getHeaderBody('To') ?: []; + } + + /** + * @return $this + */ + public function addCc(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('Cc', $addresses); + } + + /** + * @return $this + */ + public function cc(Address|string ...$addresses): static + { + return $this->setListAddressHeaderBody('Cc', $addresses); + } + + /** + * @return Address[] + */ + public function getCc(): array + { + return $this->getHeaders()->getHeaderBody('Cc') ?: []; + } + + /** + * @return $this + */ + public function addBcc(Address|string ...$addresses): static + { + return $this->addListAddressHeaderBody('Bcc', $addresses); + } + + /** + * @return $this + */ + public function bcc(Address|string ...$addresses): static + { + return $this->setListAddressHeaderBody('Bcc', $addresses); + } + + /** + * @return Address[] + */ + public function getBcc(): array + { + return $this->getHeaders()->getHeaderBody('Bcc') ?: []; + } + + /** + * Sets the priority of this message. + * + * The value is an integer where 1 is the highest priority and 5 is the lowest. + * + * @return $this + */ + public function priority(int $priority): static + { + if ($priority > 5) { + $priority = 5; + } elseif ($priority < 1) { + $priority = 1; + } + + return $this->setHeaderBody('Text', 'X-Priority', \sprintf('%d (%s)', $priority, self::PRIORITY_MAP[$priority])); + } + + /** + * Get the priority of this message. + * + * The returned value is an integer where 1 is the highest priority and 5 + * is the lowest. + */ + public function getPriority(): int + { + [$priority] = sscanf($this->getHeaders()->getHeaderBody('X-Priority') ?? '', '%[1-5]'); + + return $priority ?? 3; + } + + /** + * @param resource|string|null $body + * + * @return $this + */ + public function text($body, string $charset = 'utf-8'): static + { + if (null !== $body && !\is_string($body) && !\is_resource($body)) { + throw new \TypeError(\sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body))); + } + + $this->cachedBody = null; + $this->text = $body; + $this->textCharset = $charset; + + return $this; + } + + /** + * @return resource|string|null + */ + public function getTextBody() + { + return $this->text; + } + + public function getTextCharset(): ?string + { + return $this->textCharset; + } + + /** + * @param resource|string|null $body + * + * @return $this + */ + public function html($body, string $charset = 'utf-8'): static + { + if (null !== $body && !\is_string($body) && !\is_resource($body)) { + throw new \TypeError(\sprintf('The body must be a string, a resource or null (got "%s").', get_debug_type($body))); + } + + $this->cachedBody = null; + $this->html = $body; + $this->htmlCharset = $charset; + + return $this; + } + + /** + * @return resource|string|null + */ + public function getHtmlBody() + { + return $this->html; + } + + public function getHtmlCharset(): ?string + { + return $this->htmlCharset; + } + + /** + * @param resource|string $body + * + * @return $this + */ + public function attach($body, ?string $name = null, ?string $contentType = null): static + { + return $this->addPart(new DataPart($body, $name, $contentType)); + } + + /** + * @return $this + */ + public function attachFromPath(string $path, ?string $name = null, ?string $contentType = null): static + { + return $this->addPart(new DataPart(new File($path), $name, $contentType)); + } + + /** + * @param resource|string $body + * + * @return $this + */ + public function embed($body, ?string $name = null, ?string $contentType = null): static + { + return $this->addPart((new DataPart($body, $name, $contentType))->asInline()); + } + + /** + * @return $this + */ + public function embedFromPath(string $path, ?string $name = null, ?string $contentType = null): static + { + return $this->addPart((new DataPart(new File($path), $name, $contentType))->asInline()); + } + + /** + * @return $this + * + * @deprecated since Symfony 6.2, use addPart() instead + */ + public function attachPart(DataPart $part): static + { + @trigger_deprecation('symfony/mime', '6.2', 'The "%s()" method is deprecated, use "addPart()" instead.', __METHOD__); + + return $this->addPart($part); + } + + /** + * @return $this + */ + public function addPart(DataPart $part): static + { + $this->cachedBody = null; + $this->attachments[] = $part; + + return $this; + } + + /** + * @return DataPart[] + */ + public function getAttachments(): array + { + return $this->attachments; + } + + public function getBody(): AbstractPart + { + if (null !== $body = parent::getBody()) { + return $body; + } + + return $this->generateBody(); + } + + /** + * @return void + */ + public function ensureValidity() + { + $this->ensureBodyValid(); + + if ('1' === $this->getHeaders()->getHeaderBody('X-Unsent')) { + throw new LogicException('Cannot send messages marked as "draft".'); + } + + parent::ensureValidity(); + } + + private function ensureBodyValid(): void + { + if (null === $this->text && null === $this->html && !$this->attachments && null === parent::getBody()) { + throw new LogicException('A message must have a text or an HTML part or attachments.'); + } + } + + /** + * Generates an AbstractPart based on the raw body of a message. + * + * The most "complex" part generated by this method is when there is text and HTML bodies + * with related images for the HTML part and some attachments: + * + * multipart/mixed + * | + * |------------> multipart/related + * | | + * | |------------> multipart/alternative + * | | | + * | | ------------> text/plain (with content) + * | | | + * | | ------------> text/html (with content) + * | | + * | ------------> image/png (with content) + * | + * ------------> application/pdf (with content) + */ + private function generateBody(): AbstractPart + { + if (null !== $this->cachedBody) { + return $this->cachedBody; + } + + $this->ensureBodyValid(); + + [$htmlPart, $otherParts, $relatedParts] = $this->prepareParts(); + + $part = null === $this->text ? null : new TextPart($this->text, $this->textCharset); + if (null !== $htmlPart) { + if (null !== $part) { + $part = new AlternativePart($part, $htmlPart); + } else { + $part = $htmlPart; + } + } + + if ($relatedParts) { + $part = new RelatedPart($part, ...$relatedParts); + } + + if ($otherParts) { + if ($part) { + $part = new MixedPart($part, ...$otherParts); + } else { + $part = new MixedPart(...$otherParts); + } + } + + return $this->cachedBody = $part; + } + + private function prepareParts(): ?array + { + $names = []; + $htmlPart = null; + $html = $this->html; + if (null !== $html) { + $htmlPart = new TextPart($html, $this->htmlCharset, 'html'); + $html = $htmlPart->getBody(); + + $regexes = [ + ']*src\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+))', + '<\w+\s+[^>]*background\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+))', + ]; + $tmpMatches = []; + foreach ($regexes as $regex) { + preg_match_all('/'.$regex.'/i', $html, $tmpMatches); + $names = array_merge($names, $tmpMatches[2], $tmpMatches[3]); + } + $names = array_filter(array_unique($names)); + } + + $otherParts = $relatedParts = []; + foreach ($this->attachments as $part) { + foreach ($names as $name) { + if ($name !== $part->getName() && (!$part->hasContentId() || $name !== $part->getContentId())) { + continue; + } + if (isset($relatedParts[$name])) { + continue 2; + } + + if ($name !== $part->getContentId()) { + $html = str_replace('cid:'.$name, 'cid:'.$part->getContentId(), $html, $count); + } + $relatedParts[$name] = $part; + $part->setName($part->getContentId())->asInline(); + + continue 2; + } + + $otherParts[] = $part; + } + if (null !== $htmlPart) { + $htmlPart = new TextPart($html, $this->htmlCharset, 'html'); + } + + return [$htmlPart, $otherParts, array_values($relatedParts)]; + } + + /** + * @return $this + */ + private function setHeaderBody(string $type, string $name, $body): static + { + $this->getHeaders()->setHeaderBody($type, $name, $body); + + return $this; + } + + /** + * @return $this + */ + private function addListAddressHeaderBody(string $name, array $addresses): static + { + if (!$header = $this->getHeaders()->get($name)) { + return $this->setListAddressHeaderBody($name, $addresses); + } + $header->addAddresses(Address::createArray($addresses)); + + return $this; + } + + /** + * @return $this + */ + private function setListAddressHeaderBody(string $name, array $addresses): static + { + $addresses = Address::createArray($addresses); + $headers = $this->getHeaders(); + if ($header = $headers->get($name)) { + $header->setAddresses($addresses); + } else { + $headers->addMailboxListHeader($name, $addresses); + } + + return $this; + } + + /** + * @internal + */ + public function __serialize(): array + { + if (\is_resource($this->text)) { + $this->text = (new TextPart($this->text))->getBody(); + } + + if (\is_resource($this->html)) { + $this->html = (new TextPart($this->html))->getBody(); + } + + return [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, parent::__serialize()]; + } + + /** + * @internal + */ + public function __unserialize(array $data): void + { + [$this->text, $this->textCharset, $this->html, $this->htmlCharset, $this->attachments, $parentData] = $data; + + parent::__unserialize($parentData); + } +} diff --git a/lib/symfony/mime/Encoder/AddressEncoderInterface.php b/lib/symfony/mime/Encoder/AddressEncoderInterface.php new file mode 100644 index 000000000..de477d884 --- /dev/null +++ b/lib/symfony/mime/Encoder/AddressEncoderInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +use Symfony\Component\Mime\Exception\AddressEncoderException; + +/** + * @author Christian Schmidt + */ +interface AddressEncoderInterface +{ + /** + * Encodes an email address. + * + * @throws AddressEncoderException if the email cannot be represented in + * the encoding implemented by this class + */ + public function encodeString(string $address): string; +} diff --git a/lib/symfony/mime/Encoder/Base64ContentEncoder.php b/lib/symfony/mime/Encoder/Base64ContentEncoder.php new file mode 100644 index 000000000..07cbca30f --- /dev/null +++ b/lib/symfony/mime/Encoder/Base64ContentEncoder.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +use Symfony\Component\Mime\Exception\RuntimeException; + +/** + * @author Fabien Potencier + */ +final class Base64ContentEncoder extends Base64Encoder implements ContentEncoderInterface +{ + public function encodeByteStream($stream, int $maxLineLength = 0): iterable + { + if (!\is_resource($stream)) { + throw new \TypeError(\sprintf('Method "%s" takes a stream as a first argument.', __METHOD__)); + } + + $filter = stream_filter_append($stream, 'convert.base64-encode', \STREAM_FILTER_READ, [ + 'line-length' => 0 >= $maxLineLength || 76 < $maxLineLength ? 76 : $maxLineLength, + 'line-break-chars' => "\r\n", + ]); + if (!\is_resource($filter)) { + throw new RuntimeException('Unable to set the base64 content encoder to the filter.'); + } + + while (!feof($stream)) { + yield fread($stream, 16372); + } + stream_filter_remove($filter); + } + + public function getName(): string + { + return 'base64'; + } +} diff --git a/lib/symfony/mime/Encoder/Base64Encoder.php b/lib/symfony/mime/Encoder/Base64Encoder.php new file mode 100644 index 000000000..710647857 --- /dev/null +++ b/lib/symfony/mime/Encoder/Base64Encoder.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +class Base64Encoder implements EncoderInterface +{ + /** + * Takes an unencoded string and produces a Base64 encoded string from it. + * + * Base64 encoded strings have a maximum line length of 76 characters. + * If the first line needs to be shorter, indicate the difference with + * $firstLineOffset. + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + if (0 >= $maxLineLength || 76 < $maxLineLength) { + $maxLineLength = 76; + } + + $encodedString = base64_encode($string); + $firstLine = ''; + if (0 !== $firstLineOffset) { + $firstLine = substr($encodedString, 0, $maxLineLength - $firstLineOffset)."\r\n"; + $encodedString = substr($encodedString, $maxLineLength - $firstLineOffset); + } + + return $firstLine.trim(chunk_split($encodedString, $maxLineLength, "\r\n")); + } +} diff --git a/lib/symfony/mime/Encoder/Base64MimeHeaderEncoder.php b/lib/symfony/mime/Encoder/Base64MimeHeaderEncoder.php new file mode 100644 index 000000000..5c06f6d9a --- /dev/null +++ b/lib/symfony/mime/Encoder/Base64MimeHeaderEncoder.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +final class Base64MimeHeaderEncoder extends Base64Encoder implements MimeHeaderEncoderInterface +{ + public function getName(): string + { + return 'B'; + } + + /** + * Takes an unencoded string and produces a Base64 encoded string from it. + * + * If the charset is iso-2022-jp, it uses mb_encode_mimeheader instead of + * default encodeString, otherwise pass to the parent method. + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + if ('iso-2022-jp' === strtolower($charset)) { + $old = mb_internal_encoding(); + mb_internal_encoding('utf-8'); + $newstring = mb_encode_mimeheader($string, 'iso-2022-jp', $this->getName(), "\r\n"); + mb_internal_encoding($old); + + return $newstring; + } + + return parent::encodeString($string, $charset, $firstLineOffset, $maxLineLength); + } +} diff --git a/lib/symfony/mime/Encoder/ContentEncoderInterface.php b/lib/symfony/mime/Encoder/ContentEncoderInterface.php new file mode 100644 index 000000000..a45ad04c2 --- /dev/null +++ b/lib/symfony/mime/Encoder/ContentEncoderInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +interface ContentEncoderInterface extends EncoderInterface +{ + /** + * Encodes the stream to a Generator. + * + * @param resource $stream + */ + public function encodeByteStream($stream, int $maxLineLength = 0): iterable; + + /** + * Gets the MIME name of this content encoding scheme. + */ + public function getName(): string; +} diff --git a/lib/symfony/mime/Encoder/EightBitContentEncoder.php b/lib/symfony/mime/Encoder/EightBitContentEncoder.php new file mode 100644 index 000000000..82831209e --- /dev/null +++ b/lib/symfony/mime/Encoder/EightBitContentEncoder.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Fabien Potencier + */ +final class EightBitContentEncoder implements ContentEncoderInterface +{ + public function encodeByteStream($stream, int $maxLineLength = 0): iterable + { + while (!feof($stream)) { + yield fread($stream, 16372); + } + } + + public function getName(): string + { + return '8bit'; + } + + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + return $string; + } +} diff --git a/lib/symfony/mime/Encoder/EncoderInterface.php b/lib/symfony/mime/Encoder/EncoderInterface.php new file mode 100644 index 000000000..bbf6d4886 --- /dev/null +++ b/lib/symfony/mime/Encoder/EncoderInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +interface EncoderInterface +{ + /** + * Encode a given string to produce an encoded string. + * + * @param int $firstLineOffset if first line needs to be shorter + * @param int $maxLineLength - 0 indicates the default length for this encoding + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string; +} diff --git a/lib/symfony/mime/Encoder/IdnAddressEncoder.php b/lib/symfony/mime/Encoder/IdnAddressEncoder.php new file mode 100644 index 000000000..07a32e9b3 --- /dev/null +++ b/lib/symfony/mime/Encoder/IdnAddressEncoder.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * An IDN email address encoder. + * + * Encodes the domain part of an address using IDN. This is compatible will all + * SMTP servers. + * + * Note: It leaves the local part as is. In case there are non-ASCII characters + * in the local part then it depends on the SMTP Server if this is supported. + * + * @author Christian Schmidt + */ +final class IdnAddressEncoder implements AddressEncoderInterface +{ + /** + * Encodes the domain part of an address using IDN. + */ + public function encodeString(string $address): string + { + $i = strrpos($address, '@'); + if (false !== $i) { + $local = substr($address, 0, $i); + $domain = substr($address, $i + 1); + + if (preg_match('/[^\x00-\x7F]/', $domain)) { + $address = \sprintf('%s@%s', $local, idn_to_ascii($domain, \IDNA_DEFAULT | \IDNA_USE_STD3_RULES | \IDNA_CHECK_BIDI | \IDNA_CHECK_CONTEXTJ | \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46)); + } + } + + return $address; + } +} diff --git a/lib/symfony/mime/Encoder/MimeHeaderEncoderInterface.php b/lib/symfony/mime/Encoder/MimeHeaderEncoderInterface.php new file mode 100644 index 000000000..fff2c782b --- /dev/null +++ b/lib/symfony/mime/Encoder/MimeHeaderEncoderInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +interface MimeHeaderEncoderInterface +{ + /** + * Get the MIME name of this content encoding scheme. + */ + public function getName(): string; +} diff --git a/lib/symfony/mime/Encoder/QpContentEncoder.php b/lib/symfony/mime/Encoder/QpContentEncoder.php new file mode 100644 index 000000000..777a6a96c --- /dev/null +++ b/lib/symfony/mime/Encoder/QpContentEncoder.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Lars Strojny + */ +final class QpContentEncoder implements ContentEncoderInterface +{ + public function encodeByteStream($stream, int $maxLineLength = 0): iterable + { + if (!\is_resource($stream)) { + throw new \TypeError(\sprintf('Method "%s" takes a stream as a first argument.', __METHOD__)); + } + + // we don't use PHP stream filters here as the content should be small enough + yield $this->encodeString(stream_get_contents($stream), 'utf-8', 0, $maxLineLength); + } + + public function getName(): string + { + return 'quoted-printable'; + } + + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + return $this->standardize(quoted_printable_encode($string)); + } + + /** + * Make sure CRLF is correct and HT/SPACE are in valid places. + */ + private function standardize(string $string): string + { + // transform CR or LF to CRLF + $string = preg_replace('~=0D(?!=0A)|(? substr_replace($string, '=09', -1), + 0x20 => substr_replace($string, '=20', -1), + default => $string, + }; + } +} diff --git a/lib/symfony/mime/Encoder/QpEncoder.php b/lib/symfony/mime/Encoder/QpEncoder.php new file mode 100644 index 000000000..160dde329 --- /dev/null +++ b/lib/symfony/mime/Encoder/QpEncoder.php @@ -0,0 +1,192 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +use Symfony\Component\Mime\CharacterStream; + +/** + * @author Chris Corbyn + */ +class QpEncoder implements EncoderInterface +{ + /** + * Pre-computed QP for HUGE optimization. + */ + private const QP_MAP = [ + 0 => '=00', 1 => '=01', 2 => '=02', 3 => '=03', 4 => '=04', + 5 => '=05', 6 => '=06', 7 => '=07', 8 => '=08', 9 => '=09', + 10 => '=0A', 11 => '=0B', 12 => '=0C', 13 => '=0D', 14 => '=0E', + 15 => '=0F', 16 => '=10', 17 => '=11', 18 => '=12', 19 => '=13', + 20 => '=14', 21 => '=15', 22 => '=16', 23 => '=17', 24 => '=18', + 25 => '=19', 26 => '=1A', 27 => '=1B', 28 => '=1C', 29 => '=1D', + 30 => '=1E', 31 => '=1F', 32 => '=20', 33 => '=21', 34 => '=22', + 35 => '=23', 36 => '=24', 37 => '=25', 38 => '=26', 39 => '=27', + 40 => '=28', 41 => '=29', 42 => '=2A', 43 => '=2B', 44 => '=2C', + 45 => '=2D', 46 => '=2E', 47 => '=2F', 48 => '=30', 49 => '=31', + 50 => '=32', 51 => '=33', 52 => '=34', 53 => '=35', 54 => '=36', + 55 => '=37', 56 => '=38', 57 => '=39', 58 => '=3A', 59 => '=3B', + 60 => '=3C', 61 => '=3D', 62 => '=3E', 63 => '=3F', 64 => '=40', + 65 => '=41', 66 => '=42', 67 => '=43', 68 => '=44', 69 => '=45', + 70 => '=46', 71 => '=47', 72 => '=48', 73 => '=49', 74 => '=4A', + 75 => '=4B', 76 => '=4C', 77 => '=4D', 78 => '=4E', 79 => '=4F', + 80 => '=50', 81 => '=51', 82 => '=52', 83 => '=53', 84 => '=54', + 85 => '=55', 86 => '=56', 87 => '=57', 88 => '=58', 89 => '=59', + 90 => '=5A', 91 => '=5B', 92 => '=5C', 93 => '=5D', 94 => '=5E', + 95 => '=5F', 96 => '=60', 97 => '=61', 98 => '=62', 99 => '=63', + 100 => '=64', 101 => '=65', 102 => '=66', 103 => '=67', 104 => '=68', + 105 => '=69', 106 => '=6A', 107 => '=6B', 108 => '=6C', 109 => '=6D', + 110 => '=6E', 111 => '=6F', 112 => '=70', 113 => '=71', 114 => '=72', + 115 => '=73', 116 => '=74', 117 => '=75', 118 => '=76', 119 => '=77', + 120 => '=78', 121 => '=79', 122 => '=7A', 123 => '=7B', 124 => '=7C', + 125 => '=7D', 126 => '=7E', 127 => '=7F', 128 => '=80', 129 => '=81', + 130 => '=82', 131 => '=83', 132 => '=84', 133 => '=85', 134 => '=86', + 135 => '=87', 136 => '=88', 137 => '=89', 138 => '=8A', 139 => '=8B', + 140 => '=8C', 141 => '=8D', 142 => '=8E', 143 => '=8F', 144 => '=90', + 145 => '=91', 146 => '=92', 147 => '=93', 148 => '=94', 149 => '=95', + 150 => '=96', 151 => '=97', 152 => '=98', 153 => '=99', 154 => '=9A', + 155 => '=9B', 156 => '=9C', 157 => '=9D', 158 => '=9E', 159 => '=9F', + 160 => '=A0', 161 => '=A1', 162 => '=A2', 163 => '=A3', 164 => '=A4', + 165 => '=A5', 166 => '=A6', 167 => '=A7', 168 => '=A8', 169 => '=A9', + 170 => '=AA', 171 => '=AB', 172 => '=AC', 173 => '=AD', 174 => '=AE', + 175 => '=AF', 176 => '=B0', 177 => '=B1', 178 => '=B2', 179 => '=B3', + 180 => '=B4', 181 => '=B5', 182 => '=B6', 183 => '=B7', 184 => '=B8', + 185 => '=B9', 186 => '=BA', 187 => '=BB', 188 => '=BC', 189 => '=BD', + 190 => '=BE', 191 => '=BF', 192 => '=C0', 193 => '=C1', 194 => '=C2', + 195 => '=C3', 196 => '=C4', 197 => '=C5', 198 => '=C6', 199 => '=C7', + 200 => '=C8', 201 => '=C9', 202 => '=CA', 203 => '=CB', 204 => '=CC', + 205 => '=CD', 206 => '=CE', 207 => '=CF', 208 => '=D0', 209 => '=D1', + 210 => '=D2', 211 => '=D3', 212 => '=D4', 213 => '=D5', 214 => '=D6', + 215 => '=D7', 216 => '=D8', 217 => '=D9', 218 => '=DA', 219 => '=DB', + 220 => '=DC', 221 => '=DD', 222 => '=DE', 223 => '=DF', 224 => '=E0', + 225 => '=E1', 226 => '=E2', 227 => '=E3', 228 => '=E4', 229 => '=E5', + 230 => '=E6', 231 => '=E7', 232 => '=E8', 233 => '=E9', 234 => '=EA', + 235 => '=EB', 236 => '=EC', 237 => '=ED', 238 => '=EE', 239 => '=EF', + 240 => '=F0', 241 => '=F1', 242 => '=F2', 243 => '=F3', 244 => '=F4', + 245 => '=F5', 246 => '=F6', 247 => '=F7', 248 => '=F8', 249 => '=F9', + 250 => '=FA', 251 => '=FB', 252 => '=FC', 253 => '=FD', 254 => '=FE', + 255 => '=FF', + ]; + + private static array $safeMapShare = []; + + /** + * A map of non-encoded ascii characters. + * + * @var string[] + * + * @internal + */ + protected array $safeMap = []; + + public function __construct() + { + $id = static::class; + if (!isset(self::$safeMapShare[$id])) { + $this->initSafeMap(); + self::$safeMapShare[$id] = $this->safeMap; + } else { + $this->safeMap = self::$safeMapShare[$id]; + } + } + + protected function initSafeMap(): void + { + foreach (array_merge([0x09, 0x20], range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte) { + $this->safeMap[$byte] = \chr($byte); + } + } + + /** + * Takes an unencoded string and produces a QP encoded string from it. + * + * QP encoded strings have a maximum line length of 76 characters. + * If the first line needs to be shorter, indicate the difference with + * $firstLineOffset. + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + if ($maxLineLength > 76 || $maxLineLength <= 0) { + $maxLineLength = 76; + } + + $thisLineLength = $maxLineLength - $firstLineOffset; + + $lines = []; + $lNo = 0; + $lines[$lNo] = ''; + $currentLine = &$lines[$lNo++]; + $size = $lineLen = 0; + $charStream = new CharacterStream($string, $charset); + + // Fetching more than 4 chars at one is slower, as is fetching fewer bytes + // Conveniently 4 chars is the UTF-8 safe number since UTF-8 has up to 6 + // bytes per char and (6 * 4 * 3 = 72 chars per line) * =NN is 3 bytes + while (null !== $bytes = $charStream->readBytes(4)) { + $enc = $this->encodeByteSequence($bytes, $size); + + $i = strpos($enc, '=0D=0A'); + $newLineLength = $lineLen + (false === $i ? $size : $i); + + if ($currentLine && $newLineLength >= $thisLineLength) { + $lines[$lNo] = ''; + $currentLine = &$lines[$lNo++]; + $thisLineLength = $maxLineLength; + $lineLen = 0; + } + + $currentLine .= $enc; + + if (false === $i) { + $lineLen += $size; + } else { + // 6 is the length of '=0D=0A'. + $lineLen = $size - strrpos($enc, '=0D=0A') - 6; + } + } + + return $this->standardize(implode("=\r\n", $lines)); + } + + /** + * Encode the given byte array into a verbatim QP form. + */ + private function encodeByteSequence(array $bytes, int &$size): string + { + $ret = ''; + $size = 0; + foreach ($bytes as $b) { + if (isset($this->safeMap[$b])) { + $ret .= $this->safeMap[$b]; + ++$size; + } else { + $ret .= self::QP_MAP[$b]; + $size += 3; + } + } + + return $ret; + } + + /** + * Make sure CRLF is correct and HT/SPACE are in valid places. + */ + private function standardize(string $string): string + { + $string = str_replace(["\t=0D=0A", ' =0D=0A', '=0D=0A'], ["=09\r\n", "=20\r\n", "\r\n"], $string); + + return match ($end = \ord(substr($string, -1))) { + 0x09, + 0x20 => substr_replace($string, self::QP_MAP[$end], -1), + default => $string, + }; + } +} diff --git a/lib/symfony/mime/Encoder/QpMimeHeaderEncoder.php b/lib/symfony/mime/Encoder/QpMimeHeaderEncoder.php new file mode 100644 index 000000000..d1d38375f --- /dev/null +++ b/lib/symfony/mime/Encoder/QpMimeHeaderEncoder.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +/** + * @author Chris Corbyn + */ +final class QpMimeHeaderEncoder extends QpEncoder implements MimeHeaderEncoderInterface +{ + protected function initSafeMap(): void + { + foreach (array_merge( + range(0x61, 0x7A), range(0x41, 0x5A), + range(0x30, 0x39), [0x20, 0x21, 0x2A, 0x2B, 0x2D, 0x2F] + ) as $byte) { + $this->safeMap[$byte] = \chr($byte); + } + } + + public function getName(): string + { + return 'Q'; + } + + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + return str_replace([' ', '=20', "=\r\n"], ['_', '_', "\r\n"], + parent::encodeString($string, $charset, $firstLineOffset, $maxLineLength) + ); + } +} diff --git a/lib/symfony/mime/Encoder/Rfc2231Encoder.php b/lib/symfony/mime/Encoder/Rfc2231Encoder.php new file mode 100644 index 000000000..4d93dc641 --- /dev/null +++ b/lib/symfony/mime/Encoder/Rfc2231Encoder.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Encoder; + +use Symfony\Component\Mime\CharacterStream; + +/** + * @author Chris Corbyn + */ +final class Rfc2231Encoder implements EncoderInterface +{ + /** + * Takes an unencoded string and produces a string encoded according to RFC 2231 from it. + */ + public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string + { + $lines = []; + $lineCount = 0; + $lines[] = ''; + $currentLine = &$lines[$lineCount++]; + + if (0 >= $maxLineLength) { + $maxLineLength = 75; + } + + $charStream = new CharacterStream($string, $charset); + $thisLineLength = $maxLineLength - $firstLineOffset; + + while (null !== $char = $charStream->read(4)) { + $encodedChar = rawurlencode($char); + if ('' !== $currentLine && \strlen($currentLine.$encodedChar) > $thisLineLength) { + $lines[] = ''; + $currentLine = &$lines[$lineCount++]; + $thisLineLength = $maxLineLength; + } + $currentLine .= $encodedChar; + } + + return implode("\r\n", $lines); + } +} diff --git a/lib/symfony/mime/Exception/AddressEncoderException.php b/lib/symfony/mime/Exception/AddressEncoderException.php new file mode 100644 index 000000000..51ee2e06f --- /dev/null +++ b/lib/symfony/mime/Exception/AddressEncoderException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class AddressEncoderException extends RfcComplianceException +{ +} diff --git a/lib/symfony/mime/Exception/ExceptionInterface.php b/lib/symfony/mime/Exception/ExceptionInterface.php new file mode 100644 index 000000000..11933900f --- /dev/null +++ b/lib/symfony/mime/Exception/ExceptionInterface.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/lib/symfony/mime/Exception/InvalidArgumentException.php b/lib/symfony/mime/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..e89ebae20 --- /dev/null +++ b/lib/symfony/mime/Exception/InvalidArgumentException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/lib/symfony/mime/Exception/LogicException.php b/lib/symfony/mime/Exception/LogicException.php new file mode 100644 index 000000000..0508ee73c --- /dev/null +++ b/lib/symfony/mime/Exception/LogicException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/lib/symfony/mime/Exception/RfcComplianceException.php b/lib/symfony/mime/Exception/RfcComplianceException.php new file mode 100644 index 000000000..26e4a5099 --- /dev/null +++ b/lib/symfony/mime/Exception/RfcComplianceException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class RfcComplianceException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/lib/symfony/mime/Exception/RuntimeException.php b/lib/symfony/mime/Exception/RuntimeException.php new file mode 100644 index 000000000..fb018b006 --- /dev/null +++ b/lib/symfony/mime/Exception/RuntimeException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Exception; + +/** + * @author Fabien Potencier + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/lib/symfony/mime/FileBinaryMimeTypeGuesser.php b/lib/symfony/mime/FileBinaryMimeTypeGuesser.php new file mode 100644 index 000000000..465f061a0 --- /dev/null +++ b/lib/symfony/mime/FileBinaryMimeTypeGuesser.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Exception\LogicException; + +/** + * Guesses the MIME type with the binary "file" (only available on *nix). + * + * @author Bernhard Schussek + */ +class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface +{ + private string $cmd; + + /** + * The $cmd pattern must contain a "%s" string that will be replaced + * with the file name to guess. + * + * The command output must start with the MIME type of the file. + * + * @param string $cmd The command to run to get the MIME type of a file + */ + public function __construct(string $cmd = 'file -b --mime -- %s 2>/dev/null') + { + $this->cmd = $cmd; + } + + public function isGuesserSupported(): bool + { + static $supported = null; + + if (null !== $supported) { + return $supported; + } + + if ('\\' === \DIRECTORY_SEPARATOR || !\function_exists('passthru') || !\function_exists('escapeshellarg')) { + return $supported = false; + } + + ob_start(); + passthru('command -v file', $exitStatus); + $binPath = trim(ob_get_clean()); + + return $supported = 0 === $exitStatus && '' !== $binPath; + } + + public function guessMimeType(string $path): ?string + { + if (!is_file($path) || !is_readable($path)) { + throw new InvalidArgumentException(\sprintf('The "%s" file does not exist or is not readable.', $path)); + } + + if (!$this->isGuesserSupported()) { + throw new LogicException(\sprintf('The "%s" guesser is not supported.', __CLASS__)); + } + + ob_start(); + + // need to use --mime instead of -i. see #6641 + passthru(\sprintf($this->cmd, escapeshellarg((str_starts_with($path, '-') ? './' : '').$path)), $return); + if ($return > 0) { + ob_end_clean(); + + return null; + } + + $type = trim(ob_get_clean()); + + if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\+\.]+)#i', $type, $match)) { + // it's not a type, but an error message + return null; + } + + return $match[1]; + } +} diff --git a/lib/symfony/mime/FileinfoMimeTypeGuesser.php b/lib/symfony/mime/FileinfoMimeTypeGuesser.php new file mode 100644 index 000000000..7a8b502df --- /dev/null +++ b/lib/symfony/mime/FileinfoMimeTypeGuesser.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Exception\LogicException; + +/** + * Guesses the MIME type using the PECL extension FileInfo. + * + * @author Bernhard Schussek + */ +class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface +{ + private ?string $magicFile; + + /** + * @param string|null $magicFile A magic file to use with the finfo instance + * + * @see https://php.net/finfo-open + */ + public function __construct(?string $magicFile = null) + { + $this->magicFile = $magicFile; + } + + public function isGuesserSupported(): bool + { + return \function_exists('finfo_open'); + } + + public function guessMimeType(string $path): ?string + { + if (!is_file($path) || !is_readable($path)) { + throw new InvalidArgumentException(\sprintf('The "%s" file does not exist or is not readable.', $path)); + } + + if (!$this->isGuesserSupported()) { + throw new LogicException(\sprintf('The "%s" guesser is not supported.', __CLASS__)); + } + + if (false === $finfo = new \finfo(\FILEINFO_MIME_TYPE, $this->magicFile)) { + return null; + } + $mimeType = $finfo->file($path); + + if ($mimeType && 0 === (\strlen($mimeType) % 2)) { + $mimeStart = substr($mimeType, 0, \strlen($mimeType) >> 1); + $mimeType = $mimeStart.$mimeStart === $mimeType ? $mimeStart : $mimeType; + } + + return $mimeType; + } +} diff --git a/lib/symfony/mime/Header/AbstractHeader.php b/lib/symfony/mime/Header/AbstractHeader.php new file mode 100644 index 000000000..3dc7fafb7 --- /dev/null +++ b/lib/symfony/mime/Header/AbstractHeader.php @@ -0,0 +1,302 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Encoder\QpMimeHeaderEncoder; + +/** + * An abstract base MIME Header. + * + * @author Chris Corbyn + */ +abstract class AbstractHeader implements HeaderInterface +{ + public const PHRASE_PATTERN = '(?:(?:(?:(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]+(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?)|(?:(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?"((?:(?:[ \t]*(?:\r\n))?[ \t])?(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21\x23-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])))*(?:(?:[ \t]*(?:\r\n))?[ \t])?"(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))*(?:(?:(?:(?:[ \t]*(?:\r\n))?[ \t])?(\((?:(?:(?:[ \t]*(?:\r\n))?[ \t])|(?:(?:[\x01-\x08\x0B\x0C\x0E-\x19\x7F]|[\x21-\x27\x2A-\x5B\x5D-\x7E])|(?:\\[\x00-\x08\x0B\x0C\x0E-\x7F])|(?1)))*(?:(?:[ \t]*(?:\r\n))?[ \t])?\)))|(?:(?:[ \t]*(?:\r\n))?[ \t])))?))+?)'; + + private static QpMimeHeaderEncoder $encoder; + + private string $name; + private int $lineLength = 76; + private ?string $lang = null; + private string $charset = 'utf-8'; + + public function __construct(string $name) + { + $this->name = $name; + } + + /** + * @return void + */ + public function setCharset(string $charset) + { + $this->charset = $charset; + } + + public function getCharset(): ?string + { + return $this->charset; + } + + /** + * Set the language used in this Header. + * + * For example, for US English, 'en-us'. + * + * @return void + */ + public function setLanguage(string $lang) + { + $this->lang = $lang; + } + + public function getLanguage(): ?string + { + return $this->lang; + } + + public function getName(): string + { + return $this->name; + } + + /** + * @return void + */ + public function setMaxLineLength(int $lineLength) + { + $this->lineLength = $lineLength; + } + + public function getMaxLineLength(): int + { + return $this->lineLength; + } + + public function toString(): string + { + return $this->tokensToString($this->toTokens()); + } + + /** + * Produces a compliant, formatted RFC 2822 'phrase' based on the string given. + * + * @param string $string as displayed + * @param bool $shorten the first line to make remove for header name + */ + protected function createPhrase(HeaderInterface $header, string $string, string $charset, bool $shorten = false): string + { + // Treat token as exactly what was given + $phraseStr = $string; + + // If it's not valid + if (!preg_match('/^'.self::PHRASE_PATTERN.'$/D', $phraseStr)) { + // .. but it is just ascii text, try escaping some characters + // and make it a quoted-string + if (preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x7F]*$/D', $phraseStr)) { + foreach (['\\', '"'] as $char) { + $phraseStr = str_replace($char, '\\'.$char, $phraseStr); + } + $phraseStr = '"'.$phraseStr.'"'; + } else { + // ... otherwise it needs encoding + // Determine space remaining on line if first line + if ($shorten) { + $usedLength = \strlen($header->getName().': '); + } else { + $usedLength = 0; + } + $phraseStr = $this->encodeWords($header, $string, $usedLength); + } + } elseif (str_contains($phraseStr, '(')) { + foreach (['\\', '"'] as $char) { + $phraseStr = str_replace($char, '\\'.$char, $phraseStr); + } + $phraseStr = '"'.$phraseStr.'"'; + } + + return $phraseStr; + } + + /** + * Encode needed word tokens within a string of input. + */ + protected function encodeWords(HeaderInterface $header, string $input, int $usedLength = -1): string + { + $value = ''; + $tokens = $this->getEncodableWordTokens($input); + foreach ($tokens as $token) { + // See RFC 2822, Sect 2.2 (really 2.2 ??) + if ($this->tokenNeedsEncoding($token)) { + // Don't encode starting WSP + $firstChar = substr($token, 0, 1); + switch ($firstChar) { + case ' ': + case "\t": + $value .= $firstChar; + $token = substr($token, 1); + } + + if (-1 == $usedLength) { + $usedLength = \strlen($header->getName().': ') + \strlen($value); + } + $value .= $this->getTokenAsEncodedWord($token, $usedLength); + } else { + $value .= $token; + } + } + + return $value; + } + + protected function tokenNeedsEncoding(string $token): bool + { + return (bool) preg_match('~[\x00-\x08\x10-\x19\x7F-\xFF\r\n]~', $token); + } + + /** + * Splits a string into tokens in blocks of words which can be encoded quickly. + * + * @return string[] + */ + protected function getEncodableWordTokens(string $string): array + { + $tokens = []; + $encodedToken = ''; + // Split at all whitespace boundaries + foreach (preg_split('~(?=[\t ])~', $string) as $token) { + if ($this->tokenNeedsEncoding($token)) { + $encodedToken .= $token; + } else { + if ('' !== $encodedToken) { + $tokens[] = $encodedToken; + $encodedToken = ''; + } + $tokens[] = $token; + } + } + if ('' !== $encodedToken) { + $tokens[] = $encodedToken; + } + + foreach ($tokens as $i => $token) { + // whitespace(s) between 2 encoded tokens + if ( + 0 < $i + && isset($tokens[$i + 1]) + && preg_match('~^[\t ]+$~', $token) + && $this->tokenNeedsEncoding($tokens[$i - 1]) + && $this->tokenNeedsEncoding($tokens[$i + 1]) + ) { + $tokens[$i - 1] .= $token.$tokens[$i + 1]; + array_splice($tokens, $i, 2); + } + } + + return $tokens; + } + + /** + * Get a token as an encoded word for safe insertion into headers. + */ + protected function getTokenAsEncodedWord(string $token, int $firstLineOffset = 0): string + { + self::$encoder ??= new QpMimeHeaderEncoder(); + + // Adjust $firstLineOffset to account for space needed for syntax + $charsetDecl = $this->charset; + if (null !== $this->lang) { + $charsetDecl .= '*'.$this->lang; + } + $encodingWrapperLength = \strlen('=?'.$charsetDecl.'?'.self::$encoder->getName().'??='); + + if ($firstLineOffset >= 75) { + // Does this logic need to be here? + $firstLineOffset = 0; + } + + $encodedTextLines = explode("\r\n", + self::$encoder->encodeString($token, $this->charset, $firstLineOffset, 75 - $encodingWrapperLength) + ); + + if ('iso-2022-jp' !== strtolower($this->charset)) { + // special encoding for iso-2022-jp using mb_encode_mimeheader + foreach ($encodedTextLines as $lineNum => $line) { + $encodedTextLines[$lineNum] = '=?'.$charsetDecl.'?'.self::$encoder->getName().'?'.$line.'?='; + } + } + + return implode("\r\n ", $encodedTextLines); + } + + /** + * Generates tokens from the given string which include CRLF as individual tokens. + * + * @return string[] + */ + protected function generateTokenLines(string $token): array + { + return preg_split('~(\r\n)~', $token, -1, \PREG_SPLIT_DELIM_CAPTURE); + } + + /** + * Generate a list of all tokens in the final header. + */ + protected function toTokens(?string $string = null): array + { + $string ??= $this->getBodyAsString(); + + $tokens = []; + // Generate atoms; split at all invisible boundaries followed by WSP + foreach (preg_split('~(?=[ \t])~', $string) as $token) { + $newTokens = $this->generateTokenLines($token); + foreach ($newTokens as $newToken) { + $tokens[] = $newToken; + } + } + + return $tokens; + } + + /** + * Takes an array of tokens which appear in the header and turns them into + * an RFC 2822 compliant string, adding FWSP where needed. + * + * @param string[] $tokens + */ + private function tokensToString(array $tokens): string + { + $lineCount = 0; + $headerLines = []; + $headerLines[] = $this->name.': '; + $currentLine = &$headerLines[$lineCount++]; + + // Build all tokens back into compliant header + foreach ($tokens as $i => $token) { + // Line longer than specified maximum or token was just a new line + if (("\r\n" === $token) + || ($i > 0 && \strlen($currentLine.$token) > $this->lineLength) + && '' !== $currentLine) { + $headerLines[] = ''; + $currentLine = &$headerLines[$lineCount++]; + } + + // Append token to the line + if ("\r\n" !== $token) { + $currentLine .= $token; + } + } + + // Implode with FWS (RFC 2822, 2.2.3) + return implode("\r\n", $headerLines); + } +} diff --git a/lib/symfony/mime/Header/DateHeader.php b/lib/symfony/mime/Header/DateHeader.php new file mode 100644 index 000000000..2b361802f --- /dev/null +++ b/lib/symfony/mime/Header/DateHeader.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +/** + * A Date MIME Header. + * + * @author Chris Corbyn + */ +final class DateHeader extends AbstractHeader +{ + private \DateTimeImmutable $dateTime; + + public function __construct(string $name, \DateTimeInterface $date) + { + parent::__construct($name); + + $this->setDateTime($date); + } + + /** + * @param \DateTimeInterface $body + */ + public function setBody(mixed $body): void + { + $this->setDateTime($body); + } + + public function getBody(): \DateTimeImmutable + { + return $this->getDateTime(); + } + + public function getDateTime(): \DateTimeImmutable + { + return $this->dateTime; + } + + /** + * Set the date-time of the Date in this Header. + * + * If a DateTime instance is provided, it is converted to DateTimeImmutable. + */ + public function setDateTime(\DateTimeInterface $dateTime): void + { + $this->dateTime = \DateTimeImmutable::createFromInterface($dateTime); + } + + public function getBodyAsString(): string + { + return $this->dateTime->format(\DateTimeInterface::RFC2822); + } +} diff --git a/lib/symfony/mime/Header/HeaderInterface.php b/lib/symfony/mime/Header/HeaderInterface.php new file mode 100644 index 000000000..5bc4162c3 --- /dev/null +++ b/lib/symfony/mime/Header/HeaderInterface.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +/** + * A MIME Header. + * + * @author Chris Corbyn + */ +interface HeaderInterface +{ + /** + * Sets the body. + * + * The type depends on the Header concrete class. + * + * @return void + */ + public function setBody(mixed $body); + + /** + * Gets the body. + * + * The return type depends on the Header concrete class. + */ + public function getBody(): mixed; + + /** + * @return void + */ + public function setCharset(string $charset); + + public function getCharset(): ?string; + + /** + * @return void + */ + public function setLanguage(string $lang); + + public function getLanguage(): ?string; + + public function getName(): string; + + /** + * @return void + */ + public function setMaxLineLength(int $lineLength); + + public function getMaxLineLength(): int; + + /** + * Gets this Header rendered as a compliant string. + */ + public function toString(): string; + + /** + * Gets the header's body, prepared for folding into a final header value. + * + * This is not necessarily RFC 2822 compliant since folding white space is + * not added at this stage (see {@link toString()} for that). + */ + public function getBodyAsString(): string; +} diff --git a/lib/symfony/mime/Header/Headers.php b/lib/symfony/mime/Header/Headers.php new file mode 100644 index 000000000..789d15d92 --- /dev/null +++ b/lib/symfony/mime/Header/Headers.php @@ -0,0 +1,316 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\LogicException; + +/** + * A collection of headers. + * + * @author Fabien Potencier + */ +final class Headers +{ + private const UNIQUE_HEADERS = [ + 'date', 'from', 'sender', 'reply-to', 'to', 'cc', 'bcc', + 'message-id', 'in-reply-to', 'references', 'subject', + ]; + private const HEADER_CLASS_MAP = [ + 'date' => DateHeader::class, + 'from' => MailboxListHeader::class, + 'sender' => MailboxHeader::class, + 'reply-to' => MailboxListHeader::class, + 'to' => MailboxListHeader::class, + 'cc' => MailboxListHeader::class, + 'bcc' => MailboxListHeader::class, + 'message-id' => IdentificationHeader::class, + 'in-reply-to' => [UnstructuredHeader::class, IdentificationHeader::class], // `In-Reply-To` and `References` are less strict than RFC 2822 (3.6.4) to allow users entering the original email's ... + 'references' => [UnstructuredHeader::class, IdentificationHeader::class], // ... `Message-ID`, even if that is no valid `msg-id` + 'return-path' => PathHeader::class, + ]; + + /** + * @var HeaderInterface[][] + */ + private array $headers = []; + private int $lineLength = 76; + + public function __construct(HeaderInterface ...$headers) + { + foreach ($headers as $header) { + $this->add($header); + } + } + + public function __clone() + { + foreach ($this->headers as $name => $collection) { + foreach ($collection as $i => $header) { + $this->headers[$name][$i] = clone $header; + } + } + } + + public function setMaxLineLength(int $lineLength): void + { + $this->lineLength = $lineLength; + foreach ($this->all() as $header) { + $header->setMaxLineLength($lineLength); + } + } + + public function getMaxLineLength(): int + { + return $this->lineLength; + } + + /** + * @param array $addresses + * + * @return $this + */ + public function addMailboxListHeader(string $name, array $addresses): static + { + return $this->add(new MailboxListHeader($name, Address::createArray($addresses))); + } + + /** + * @return $this + */ + public function addMailboxHeader(string $name, Address|string $address): static + { + return $this->add(new MailboxHeader($name, Address::create($address))); + } + + /** + * @return $this + */ + public function addIdHeader(string $name, string|array $ids): static + { + return $this->add(new IdentificationHeader($name, $ids)); + } + + /** + * @return $this + */ + public function addPathHeader(string $name, Address|string $path): static + { + return $this->add(new PathHeader($name, $path instanceof Address ? $path : new Address($path))); + } + + /** + * @return $this + */ + public function addDateHeader(string $name, \DateTimeInterface $dateTime): static + { + return $this->add(new DateHeader($name, $dateTime)); + } + + /** + * @return $this + */ + public function addTextHeader(string $name, string $value): static + { + return $this->add(new UnstructuredHeader($name, $value)); + } + + /** + * @return $this + */ + public function addParameterizedHeader(string $name, string $value, array $params = []): static + { + return $this->add(new ParameterizedHeader($name, $value, $params)); + } + + /** + * @return $this + */ + public function addHeader(string $name, mixed $argument, array $more = []): static + { + $headerClass = self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class; + if (\is_array($headerClass)) { + $headerClass = $headerClass[0]; + } + $parts = explode('\\', $headerClass); + $method = 'add'.ucfirst(array_pop($parts)); + if ('addUnstructuredHeader' === $method) { + $method = 'addTextHeader'; + } elseif ('addIdentificationHeader' === $method) { + $method = 'addIdHeader'; + } elseif ('addMailboxListHeader' === $method && !\is_array($argument)) { + $argument = [$argument]; + } + + return $this->$method($name, $argument, $more); + } + + public function has(string $name): bool + { + return isset($this->headers[strtolower($name)]); + } + + /** + * @return $this + */ + public function add(HeaderInterface $header): static + { + self::checkHeaderClass($header); + + $header->setMaxLineLength($this->lineLength); + $name = strtolower($header->getName()); + + if (\in_array($name, self::UNIQUE_HEADERS, true) && isset($this->headers[$name]) && \count($this->headers[$name]) > 0) { + throw new LogicException(\sprintf('Impossible to set header "%s" as it\'s already defined and must be unique.', $header->getName())); + } + + $this->headers[$name][] = $header; + + return $this; + } + + public function get(string $name): ?HeaderInterface + { + $name = strtolower($name); + if (!isset($this->headers[$name])) { + return null; + } + + $values = array_values($this->headers[$name]); + + return array_shift($values); + } + + public function all(?string $name = null): iterable + { + if (null === $name) { + foreach ($this->headers as $name => $collection) { + foreach ($collection as $header) { + yield $name => $header; + } + } + } elseif (isset($this->headers[strtolower($name)])) { + foreach ($this->headers[strtolower($name)] as $header) { + yield $header; + } + } + } + + public function getNames(): array + { + return array_keys($this->headers); + } + + public function remove(string $name): void + { + unset($this->headers[strtolower($name)]); + } + + public static function isUniqueHeader(string $name): bool + { + return \in_array(strtolower($name), self::UNIQUE_HEADERS, true); + } + + /** + * @throws LogicException if the header name and class are not compatible + */ + public static function checkHeaderClass(HeaderInterface $header): void + { + $name = strtolower($header->getName()); + $headerClasses = self::HEADER_CLASS_MAP[$name] ?? []; + if (!\is_array($headerClasses)) { + $headerClasses = [$headerClasses]; + } + + if (!$headerClasses) { + return; + } + + foreach ($headerClasses as $c) { + if ($header instanceof $c) { + return; + } + } + + throw new LogicException(\sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), implode('" or "', $headerClasses), get_debug_type($header))); + } + + public function toString(): string + { + $string = ''; + foreach ($this->toArray() as $str) { + $string .= $str."\r\n"; + } + + return $string; + } + + public function toArray(): array + { + $arr = []; + foreach ($this->all() as $header) { + if ('' !== $header->getBodyAsString()) { + $arr[] = $header->toString(); + } + } + + return $arr; + } + + public function getHeaderBody(string $name): mixed + { + return $this->has($name) ? $this->get($name)->getBody() : null; + } + + /** + * @internal + */ + public function setHeaderBody(string $type, string $name, mixed $body): void + { + if ($this->has($name)) { + $this->get($name)->setBody($body); + } else { + $this->{'add'.$type.'Header'}($name, $body); + } + } + + public function getHeaderParameter(string $name, string $parameter): ?string + { + if (!$this->has($name)) { + return null; + } + + $header = $this->get($name); + if (!$header instanceof ParameterizedHeader) { + throw new LogicException(\sprintf('Unable to get parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class)); + } + + return $header->getParameter($parameter); + } + + /** + * @internal + */ + public function setHeaderParameter(string $name, string $parameter, ?string $value): void + { + if (!$this->has($name)) { + throw new LogicException(\sprintf('Unable to set parameter "%s" on header "%s" as the header is not defined.', $parameter, $name)); + } + + $header = $this->get($name); + if (!$header instanceof ParameterizedHeader) { + throw new LogicException(\sprintf('Unable to set parameter "%s" on header "%s" as the header is not of class "%s".', $parameter, $name, ParameterizedHeader::class)); + } + + $header->setParameter($parameter, $value); + } +} diff --git a/lib/symfony/mime/Header/IdentificationHeader.php b/lib/symfony/mime/Header/IdentificationHeader.php new file mode 100644 index 000000000..14e18bf25 --- /dev/null +++ b/lib/symfony/mime/Header/IdentificationHeader.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * An ID MIME Header for something like Message-ID or Content-ID (one or more addresses). + * + * @author Chris Corbyn + */ +final class IdentificationHeader extends AbstractHeader +{ + private array $ids = []; + private array $idsAsAddresses = []; + + public function __construct(string $name, string|array $ids) + { + parent::__construct($name); + + $this->setId($ids); + } + + /** + * @param string|string[] $body a string ID or an array of IDs + * + * @throws RfcComplianceException + */ + public function setBody(mixed $body): void + { + $this->setId($body); + } + + public function getBody(): array + { + return $this->getIds(); + } + + /** + * Set the ID used in the value of this header. + * + * @param string|string[] $id + * + * @throws RfcComplianceException + */ + public function setId(string|array $id): void + { + $this->setIds(\is_array($id) ? $id : [$id]); + } + + /** + * Get the ID used in the value of this Header. + * + * If multiple IDs are set only the first is returned. + */ + public function getId(): ?string + { + return $this->ids[0] ?? null; + } + + /** + * Set a collection of IDs to use in the value of this Header. + * + * @param string[] $ids + * + * @throws RfcComplianceException + */ + public function setIds(array $ids): void + { + $this->ids = []; + $this->idsAsAddresses = []; + foreach ($ids as $id) { + $this->idsAsAddresses[] = new Address($id); + $this->ids[] = $id; + } + } + + /** + * Get the list of IDs used in this Header. + * + * @return string[] + */ + public function getIds(): array + { + return $this->ids; + } + + public function getBodyAsString(): string + { + $addrs = []; + foreach ($this->idsAsAddresses as $address) { + $addrs[] = '<'.$address->toString().'>'; + } + + return implode(' ', $addrs); + } +} diff --git a/lib/symfony/mime/Header/MailboxHeader.php b/lib/symfony/mime/Header/MailboxHeader.php new file mode 100644 index 000000000..8ba964b53 --- /dev/null +++ b/lib/symfony/mime/Header/MailboxHeader.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * A Mailbox MIME Header for something like Sender (one named address). + * + * @author Fabien Potencier + */ +final class MailboxHeader extends AbstractHeader +{ + private Address $address; + + public function __construct(string $name, Address $address) + { + parent::__construct($name); + + $this->setAddress($address); + } + + /** + * @param Address $body + * + * @throws RfcComplianceException + */ + public function setBody(mixed $body): void + { + $this->setAddress($body); + } + + /** + * @throws RfcComplianceException + */ + public function getBody(): Address + { + return $this->getAddress(); + } + + /** + * @throws RfcComplianceException + */ + public function setAddress(Address $address): void + { + $this->address = $address; + } + + public function getAddress(): Address + { + return $this->address; + } + + public function getBodyAsString(): string + { + $str = $this->address->getEncodedAddress(); + if ($name = $this->address->getName()) { + $str = $this->createPhrase($this, $name, $this->getCharset(), true).' <'.$str.'>'; + } + + return $str; + } + + /** + * Redefine the encoding requirements for an address. + * + * All "specials" must be encoded as the full header value will not be quoted + * + * @see RFC 2822 3.2.1 + */ + protected function tokenNeedsEncoding(string $token): bool + { + return preg_match('/[()<>\[\]:;@\,."]/', $token) || parent::tokenNeedsEncoding($token); + } +} diff --git a/lib/symfony/mime/Header/MailboxListHeader.php b/lib/symfony/mime/Header/MailboxListHeader.php new file mode 100644 index 000000000..8d902fb75 --- /dev/null +++ b/lib/symfony/mime/Header/MailboxListHeader.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * A Mailbox list MIME Header for something like From, To, Cc, and Bcc (one or more named addresses). + * + * @author Chris Corbyn + */ +final class MailboxListHeader extends AbstractHeader +{ + private array $addresses = []; + + /** + * @param Address[] $addresses + */ + public function __construct(string $name, array $addresses) + { + parent::__construct($name); + + $this->setAddresses($addresses); + } + + /** + * @param Address[] $body + * + * @throws RfcComplianceException + */ + public function setBody(mixed $body): void + { + $this->setAddresses($body); + } + + /** + * @return Address[] + * + * @throws RfcComplianceException + */ + public function getBody(): array + { + return $this->getAddresses(); + } + + /** + * Sets a list of addresses to be shown in this Header. + * + * @param Address[] $addresses + * + * @throws RfcComplianceException + */ + public function setAddresses(array $addresses): void + { + $this->addresses = []; + $this->addAddresses($addresses); + } + + /** + * Sets a list of addresses to be shown in this Header. + * + * @param Address[] $addresses + * + * @throws RfcComplianceException + */ + public function addAddresses(array $addresses): void + { + foreach ($addresses as $address) { + $this->addAddress($address); + } + } + + /** + * @throws RfcComplianceException + */ + public function addAddress(Address $address): void + { + $this->addresses[] = $address; + } + + /** + * @return Address[] + */ + public function getAddresses(): array + { + return $this->addresses; + } + + /** + * Gets the full mailbox list of this Header as an array of valid RFC 2822 strings. + * + * @return string[] + * + * @throws RfcComplianceException + */ + public function getAddressStrings(): array + { + $strings = []; + foreach ($this->addresses as $address) { + $str = $address->getEncodedAddress(); + if ($name = $address->getName()) { + $str = $this->createPhrase($this, $name, $this->getCharset(), !$strings).' <'.$str.'>'; + } + $strings[] = $str; + } + + return $strings; + } + + public function getBodyAsString(): string + { + return implode(', ', $this->getAddressStrings()); + } + + /** + * Redefine the encoding requirements for addresses. + * + * All "specials" must be encoded as the full header value will not be quoted + * + * @see RFC 2822 3.2.1 + */ + protected function tokenNeedsEncoding(string $token): bool + { + return preg_match('/[()<>\[\]:;@\,."]/', $token) || parent::tokenNeedsEncoding($token); + } +} diff --git a/lib/symfony/mime/Header/ParameterizedHeader.php b/lib/symfony/mime/Header/ParameterizedHeader.php new file mode 100644 index 000000000..5ef4f2120 --- /dev/null +++ b/lib/symfony/mime/Header/ParameterizedHeader.php @@ -0,0 +1,191 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Encoder\Rfc2231Encoder; + +/** + * @author Chris Corbyn + */ +final class ParameterizedHeader extends UnstructuredHeader +{ + /** + * RFC 2231's definition of a token. + * + * @var string + */ + public const TOKEN_REGEX = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)'; + + private ?Rfc2231Encoder $encoder = null; + private array $parameters = []; + + public function __construct(string $name, string $value, array $parameters = []) + { + parent::__construct($name, $value); + + foreach ($parameters as $k => $v) { + $this->setParameter($k, $v); + } + + if ('content-type' !== strtolower($name)) { + $this->encoder = new Rfc2231Encoder(); + } + } + + public function setParameter(string $parameter, ?string $value): void + { + $this->setParameters(array_merge($this->getParameters(), [$parameter => $value])); + } + + public function getParameter(string $parameter): string + { + return $this->getParameters()[$parameter] ?? ''; + } + + /** + * @param string[] $parameters + */ + public function setParameters(array $parameters): void + { + $this->parameters = $parameters; + } + + /** + * @return string[] + */ + public function getParameters(): array + { + return $this->parameters; + } + + public function getBodyAsString(): string + { + $body = parent::getBodyAsString(); + foreach ($this->parameters as $name => $value) { + if (null !== $value) { + $body .= '; '.$this->createParameter($name, $value); + } + } + + return $body; + } + + /** + * Generate a list of all tokens in the final header. + * + * This doesn't need to be overridden in theory, but it is for implementation + * reasons to prevent potential breakage of attributes. + */ + protected function toTokens(?string $string = null): array + { + $tokens = parent::toTokens(parent::getBodyAsString()); + + // Try creating any parameters + foreach ($this->parameters as $name => $value) { + if (null !== $value) { + // Add the semi-colon separator + $tokens[\count($tokens) - 1] .= ';'; + $tokens = array_merge($tokens, $this->generateTokenLines(' '.$this->createParameter($name, $value))); + } + } + + return $tokens; + } + + /** + * Render an RFC 2047 compliant header parameter from the $name and $value. + */ + private function createParameter(string $name, string $value): string + { + $origValue = $value; + + $encoded = false; + // Allow room for parameter name, indices, "=" and DQUOTEs + $maxValueLength = $this->getMaxLineLength() - \strlen($name.'=*N"";') - 1; + $firstLineOffset = 0; + + // If it's not already a valid parameter value... + if (!preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) { + // TODO: text, or something else?? + // ... and it's not ascii + if (!preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x7F]*$/D', $value)) { + $encoded = true; + // Allow space for the indices, charset and language + $maxValueLength = $this->getMaxLineLength() - \strlen($name.'*N*="";') - 1; + $firstLineOffset = \strlen($this->getCharset()."'".$this->getLanguage()."'"); + } + + if (\in_array($name, ['name', 'filename'], true) && 'form-data' === $this->getValue() && 'content-disposition' === strtolower($this->getName()) && preg_match('//u', $value)) { + // WHATWG HTML living standard 4.10.21.8 2 specifies: + // For field names and filenames for file fields, the result of the + // encoding in the previous bullet point must be escaped by replacing + // any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D` + // and 0x22 (") with `%22`. + // The user agent must not perform any other escapes. + $value = str_replace(['"', "\r", "\n"], ['%22', '%0D', '%0A'], $value); + + if (\strlen($value) <= $maxValueLength) { + return $name.'="'.$value.'"'; + } + + $value = $origValue; + } + } + + // Encode if we need to + if ($encoded || \strlen($value) > $maxValueLength) { + if (null !== $this->encoder) { + $value = $this->encoder->encodeString($origValue, $this->getCharset(), $firstLineOffset, $maxValueLength); + } else { + // We have to go against RFC 2183/2231 in some areas for interoperability + $value = $this->getTokenAsEncodedWord($origValue); + $encoded = false; + } + } + + $valueLines = $this->encoder ? explode("\r\n", $value) : [$value]; + + // Need to add indices + if (\count($valueLines) > 1) { + $paramLines = []; + foreach ($valueLines as $i => $line) { + $paramLines[] = $name.'*'.$i.$this->getEndOfParameterValue($line, true, 0 === $i); + } + + return implode(";\r\n ", $paramLines); + } else { + return $name.$this->getEndOfParameterValue($valueLines[0], $encoded, true); + } + } + + /** + * Returns the parameter value from the "=" and beyond. + * + * @param string $value to append + */ + private function getEndOfParameterValue(string $value, bool $encoded = false, bool $firstLine = false): string + { + $forceHttpQuoting = 'form-data' === $this->getValue() && 'content-disposition' === strtolower($this->getName()); + if ($forceHttpQuoting || !preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) { + $value = '"'.$value.'"'; + } + $prepend = '='; + if ($encoded) { + $prepend = '*='; + if ($firstLine) { + $prepend = '*='.$this->getCharset()."'".$this->getLanguage()."'"; + } + } + + return $prepend.$value; + } +} diff --git a/lib/symfony/mime/Header/PathHeader.php b/lib/symfony/mime/Header/PathHeader.php new file mode 100644 index 000000000..4b0b7d395 --- /dev/null +++ b/lib/symfony/mime/Header/PathHeader.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Exception\RfcComplianceException; + +/** + * A Path Header, such a Return-Path (one address). + * + * @author Chris Corbyn + */ +final class PathHeader extends AbstractHeader +{ + private Address $address; + + public function __construct(string $name, Address $address) + { + parent::__construct($name); + + $this->setAddress($address); + } + + /** + * @param Address $body + * + * @throws RfcComplianceException + */ + public function setBody(mixed $body): void + { + $this->setAddress($body); + } + + public function getBody(): Address + { + return $this->getAddress(); + } + + public function setAddress(Address $address): void + { + $this->address = $address; + } + + public function getAddress(): Address + { + return $this->address; + } + + public function getBodyAsString(): string + { + return '<'.$this->address->getEncodedAddress().'>'; + } +} diff --git a/lib/symfony/mime/Header/UnstructuredHeader.php b/lib/symfony/mime/Header/UnstructuredHeader.php new file mode 100644 index 000000000..61c06d8f5 --- /dev/null +++ b/lib/symfony/mime/Header/UnstructuredHeader.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Header; + +/** + * A Simple MIME Header. + * + * @author Chris Corbyn + */ +class UnstructuredHeader extends AbstractHeader +{ + private string $value; + + public function __construct(string $name, string $value) + { + parent::__construct($name); + + $this->setValue($value); + } + + /** + * @param string $body + * + * @return void + */ + public function setBody(mixed $body) + { + $this->setValue($body); + } + + public function getBody(): string + { + return $this->getValue(); + } + + /** + * Get the (unencoded) value of this header. + */ + public function getValue(): string + { + return $this->value; + } + + /** + * Set the (unencoded) value of this header. + * + * @return void + */ + public function setValue(string $value) + { + $this->value = $value; + } + + /** + * Get the value of this header prepared for rendering. + */ + public function getBodyAsString(): string + { + return $this->encodeWords($this, $this->value); + } +} diff --git a/lib/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php b/lib/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php new file mode 100644 index 000000000..2aaf8e6c4 --- /dev/null +++ b/lib/symfony/mime/HtmlToTextConverter/DefaultHtmlToTextConverter.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\HtmlToTextConverter; + +/** + * @author Fabien Potencier + */ +class DefaultHtmlToTextConverter implements HtmlToTextConverterInterface +{ + public function convert(string $html, string $charset): string + { + return strip_tags(preg_replace('{<(head|style)\b.*?}is', '', $html)); + } +} diff --git a/lib/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php b/lib/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php new file mode 100644 index 000000000..696f37ccf --- /dev/null +++ b/lib/symfony/mime/HtmlToTextConverter/HtmlToTextConverterInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\HtmlToTextConverter; + +/** + * @author Fabien Potencier + */ +interface HtmlToTextConverterInterface +{ + /** + * Converts an HTML representation of a Message to a text representation. + * + * The output must use the same charset as the HTML one. + */ + public function convert(string $html, string $charset): string; +} diff --git a/lib/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php b/lib/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php new file mode 100644 index 000000000..253a7b19f --- /dev/null +++ b/lib/symfony/mime/HtmlToTextConverter/LeagueHtmlToMarkdownConverter.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\HtmlToTextConverter; + +use League\HTMLToMarkdown\HtmlConverter; +use League\HTMLToMarkdown\HtmlConverterInterface; + +/** + * @author Fabien Potencier + */ +class LeagueHtmlToMarkdownConverter implements HtmlToTextConverterInterface +{ + public function __construct( + private HtmlConverterInterface $converter = new HtmlConverter([ + 'hard_break' => true, + 'strip_tags' => true, + 'remove_nodes' => 'head style', + ]), + ) { + } + + public function convert(string $html, string $charset): string + { + return $this->converter->convert($html); + } +} diff --git a/lib/symfony/mime/LICENSE b/lib/symfony/mime/LICENSE new file mode 100644 index 000000000..4dd83ce0f --- /dev/null +++ b/lib/symfony/mime/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/symfony/mime/Message.php b/lib/symfony/mime/Message.php new file mode 100644 index 000000000..fc8940ebd --- /dev/null +++ b/lib/symfony/mime/Message.php @@ -0,0 +1,169 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\LogicException; +use Symfony\Component\Mime\Header\Headers; +use Symfony\Component\Mime\Part\AbstractPart; +use Symfony\Component\Mime\Part\TextPart; + +/** + * @author Fabien Potencier + */ +class Message extends RawMessage +{ + private Headers $headers; + private ?AbstractPart $body; + + public function __construct(?Headers $headers = null, ?AbstractPart $body = null) + { + $this->headers = $headers ? clone $headers : new Headers(); + $this->body = $body; + } + + public function __clone() + { + $this->headers = clone $this->headers; + + if (null !== $this->body) { + $this->body = clone $this->body; + } + } + + /** + * @return $this + */ + public function setBody(?AbstractPart $body = null): static + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/mime', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + $this->body = $body; + + return $this; + } + + public function getBody(): ?AbstractPart + { + return $this->body; + } + + /** + * @return $this + */ + public function setHeaders(Headers $headers): static + { + $this->headers = $headers; + + return $this; + } + + public function getHeaders(): Headers + { + return $this->headers; + } + + public function getPreparedHeaders(): Headers + { + $headers = clone $this->headers; + + if (!$headers->has('From')) { + if (!$headers->has('Sender')) { + throw new LogicException('An email must have a "From" or a "Sender" header.'); + } + $headers->addMailboxListHeader('From', [$headers->get('Sender')->getAddress()]); + } + + if (!$headers->has('MIME-Version')) { + $headers->addTextHeader('MIME-Version', '1.0'); + } + + if (!$headers->has('Date')) { + $headers->addDateHeader('Date', new \DateTimeImmutable()); + } + + // determine the "real" sender + if (!$headers->has('Sender') && \count($froms = $headers->get('From')->getAddresses()) > 1) { + $headers->addMailboxHeader('Sender', $froms[0]); + } + + if (!$headers->has('Message-ID')) { + $headers->addIdHeader('Message-ID', $this->generateMessageId()); + } + + // remove the Bcc field which should NOT be part of the sent message + $headers->remove('Bcc'); + + return $headers; + } + + public function toString(): string + { + if (null === $body = $this->getBody()) { + $body = new TextPart(''); + } + + return $this->getPreparedHeaders()->toString().$body->toString(); + } + + public function toIterable(): iterable + { + if (null === $body = $this->getBody()) { + $body = new TextPart(''); + } + + yield $this->getPreparedHeaders()->toString(); + yield from $body->toIterable(); + } + + /** + * @return void + */ + public function ensureValidity() + { + if (!$this->headers->get('To')?->getBody() && !$this->headers->get('Cc')?->getBody() && !$this->headers->get('Bcc')?->getBody()) { + throw new LogicException('An email must have a "To", "Cc", or "Bcc" header.'); + } + + if (!$this->headers->get('From')?->getBody() && !$this->headers->get('Sender')?->getBody()) { + throw new LogicException('An email must have a "From" or a "Sender" header.'); + } + + parent::ensureValidity(); + } + + public function generateMessageId(): string + { + if ($this->headers->has('Sender')) { + $sender = $this->headers->get('Sender')->getAddress(); + } elseif ($this->headers->has('From')) { + if (!$froms = $this->headers->get('From')->getAddresses()) { + throw new LogicException('A "From" header must have at least one email address.'); + } + $sender = $froms[0]; + } else { + throw new LogicException('An email must have a "From" or a "Sender" header.'); + } + + return bin2hex(random_bytes(16)).strstr($sender->getAddress(), '@'); + } + + public function __serialize(): array + { + return [$this->headers, $this->body]; + } + + public function __unserialize(array $data): void + { + [$this->headers, $this->body] = $data; + } +} diff --git a/lib/symfony/mime/MessageConverter.php b/lib/symfony/mime/MessageConverter.php new file mode 100644 index 000000000..a07dd8720 --- /dev/null +++ b/lib/symfony/mime/MessageConverter.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\RuntimeException; +use Symfony\Component\Mime\Part\DataPart; +use Symfony\Component\Mime\Part\Multipart\AlternativePart; +use Symfony\Component\Mime\Part\Multipart\MixedPart; +use Symfony\Component\Mime\Part\Multipart\RelatedPart; +use Symfony\Component\Mime\Part\TextPart; + +/** + * @author Fabien Potencier + */ +final class MessageConverter +{ + /** + * @throws RuntimeException when unable to convert the message to an email + */ + public static function toEmail(Message $message): Email + { + if ($message instanceof Email) { + return $message; + } + + // try to convert to a "simple" Email instance + $body = $message->getBody(); + if ($body instanceof TextPart) { + return self::createEmailFromTextPart($message, $body); + } + + if ($body instanceof AlternativePart) { + return self::createEmailFromAlternativePart($message, $body); + } + + if ($body instanceof RelatedPart) { + return self::createEmailFromRelatedPart($message, $body); + } + + if ($body instanceof MixedPart) { + $parts = $body->getParts(); + if ($parts[0] instanceof RelatedPart) { + $email = self::createEmailFromRelatedPart($message, $parts[0]); + } elseif ($parts[0] instanceof AlternativePart) { + $email = self::createEmailFromAlternativePart($message, $parts[0]); + } elseif ($parts[0] instanceof TextPart) { + $email = self::createEmailFromTextPart($message, $parts[0]); + } else { + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + return self::addParts($email, \array_slice($parts, 1)); + } + + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + private static function createEmailFromTextPart(Message $message, TextPart $part): Email + { + if ('text' === $part->getMediaType() && 'plain' === $part->getMediaSubtype()) { + return (new Email(clone $message->getHeaders()))->text($part->getBody(), $part->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8'); + } + if ('text' === $part->getMediaType() && 'html' === $part->getMediaSubtype()) { + return (new Email(clone $message->getHeaders()))->html($part->getBody(), $part->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8'); + } + + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + private static function createEmailFromAlternativePart(Message $message, AlternativePart $part): Email + { + $parts = $part->getParts(); + if ( + 2 === \count($parts) + && $parts[0] instanceof TextPart && 'text' === $parts[0]->getMediaType() && 'plain' === $parts[0]->getMediaSubtype() + && $parts[1] instanceof TextPart && 'text' === $parts[1]->getMediaType() && 'html' === $parts[1]->getMediaSubtype() + ) { + return (new Email(clone $message->getHeaders())) + ->text($parts[0]->getBody(), $parts[0]->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8') + ->html($parts[1]->getBody(), $parts[1]->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8') + ; + } + + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + private static function createEmailFromRelatedPart(Message $message, RelatedPart $part): Email + { + $parts = $part->getParts(); + if ($parts[0] instanceof AlternativePart) { + $email = self::createEmailFromAlternativePart($message, $parts[0]); + } elseif ($parts[0] instanceof TextPart) { + $email = self::createEmailFromTextPart($message, $parts[0]); + } else { + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message))); + } + + return self::addParts($email, \array_slice($parts, 1)); + } + + private static function addParts(Email $email, array $parts): Email + { + foreach ($parts as $part) { + if (!$part instanceof DataPart) { + throw new RuntimeException(\sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($email))); + } + + $email->addPart($part); + } + + return $email; + } +} diff --git a/lib/symfony/mime/MimeTypeGuesserInterface.php b/lib/symfony/mime/MimeTypeGuesserInterface.php new file mode 100644 index 000000000..30ee3b64a --- /dev/null +++ b/lib/symfony/mime/MimeTypeGuesserInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +/** + * Guesses the MIME type of a file. + * + * @author Fabien Potencier + */ +interface MimeTypeGuesserInterface +{ + /** + * Returns true if this guesser is supported. + */ + public function isGuesserSupported(): bool; + + /** + * Guesses the MIME type of the file with the given path. + * + * @throws \LogicException If the guesser is not supported + * @throws \InvalidArgumentException If the file does not exist or is not readable + */ + public function guessMimeType(string $path): ?string; +} diff --git a/lib/symfony/mime/MimeTypes.php b/lib/symfony/mime/MimeTypes.php new file mode 100644 index 000000000..19628b0b1 --- /dev/null +++ b/lib/symfony/mime/MimeTypes.php @@ -0,0 +1,3655 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\LogicException; + +/** + * Manages MIME types and file extensions. + * + * For MIME type guessing, you can register custom guessers + * by calling the registerGuesser() method. + * Custom guessers are always called before any default ones: + * + * $guesser = new MimeTypes(); + * $guesser->registerGuesser(new MyCustomMimeTypeGuesser()); + * + * If you want to change the order of the default guessers, just re-register your + * preferred one as a custom one. The last registered guesser is preferred over + * previously registered ones. + * + * Re-registering a built-in guesser also allows you to configure it: + * + * $guesser = new MimeTypes(); + * $guesser->registerGuesser(new FileinfoMimeTypeGuesser('/path/to/magic/file')); + * + * @author Fabien Potencier + */ +final class MimeTypes implements MimeTypesInterface +{ + private array $extensions = []; + private array $mimeTypes = []; + + /** + * @var MimeTypeGuesserInterface[] + */ + private array $guessers = []; + private static MimeTypes $default; + + public function __construct(array $map = []) + { + foreach ($map as $mimeType => $extensions) { + $this->extensions[$mimeType] = $extensions; + + foreach ($extensions as $extension) { + $this->mimeTypes[$extension][] = $mimeType; + } + } + $this->registerGuesser(new FileBinaryMimeTypeGuesser()); + $this->registerGuesser(new FileinfoMimeTypeGuesser()); + } + + public static function setDefault(self $default): void + { + self::$default = $default; + } + + public static function getDefault(): self + { + return self::$default ??= new self(); + } + + /** + * Registers a MIME type guesser. + * + * The last registered guesser has precedence over the other ones. + */ + public function registerGuesser(MimeTypeGuesserInterface $guesser): void + { + array_unshift($this->guessers, $guesser); + } + + public function getExtensions(string $mimeType): array + { + if ($this->extensions) { + $extensions = $this->extensions[$mimeType] ?? $this->extensions[$lcMimeType = strtolower($mimeType)] ?? null; + } + + return $extensions ?? self::MAP[$mimeType] ?? self::MAP[$lcMimeType ?? strtolower($mimeType)] ?? []; + } + + public function getMimeTypes(string $ext): array + { + if ($this->mimeTypes) { + $mimeTypes = $this->mimeTypes[$ext] ?? $this->mimeTypes[$lcExt = strtolower($ext)] ?? null; + } + + return $mimeTypes ?? self::REVERSE_MAP[$ext] ?? self::REVERSE_MAP[$lcExt ?? strtolower($ext)] ?? []; + } + + public function isGuesserSupported(): bool + { + foreach ($this->guessers as $guesser) { + if ($guesser->isGuesserSupported()) { + return true; + } + } + + return false; + } + + /** + * The file is passed to each registered MIME type guesser in reverse order + * of their registration (last registered is queried first). Once a guesser + * returns a value that is not null, this method terminates and returns the + * value. + */ + public function guessMimeType(string $path): ?string + { + foreach ($this->guessers as $guesser) { + if (!$guesser->isGuesserSupported()) { + continue; + } + + if (null !== $mimeType = $guesser->guessMimeType($path)) { + return $mimeType; + } + } + + if (!$this->isGuesserSupported()) { + throw new LogicException('Unable to guess the MIME type as no guessers are available (have you enabled the php_fileinfo extension?).'); + } + + return null; + } + + /** + * A map of MIME types and their default extensions. + * + * Updated from upstream on 2023-10-14. + * + * @see Resources/bin/update_mime_types.php + */ + private const MAP = [ + 'application/acrobat' => ['pdf'], + 'application/andrew-inset' => ['ez'], + 'application/annodex' => ['anx'], + 'application/applixware' => ['aw'], + 'application/atom+xml' => ['atom'], + 'application/atomcat+xml' => ['atomcat'], + 'application/atomdeleted+xml' => ['atomdeleted'], + 'application/atomsvc+xml' => ['atomsvc'], + 'application/atsc-dwd+xml' => ['dwd'], + 'application/atsc-held+xml' => ['held'], + 'application/atsc-rsat+xml' => ['rsat'], + 'application/bat' => ['bat'], + 'application/bdoc' => ['bdoc'], + 'application/bzip2' => ['bz2', 'bz'], + 'application/calendar+xml' => ['xcs'], + 'application/cbor' => ['cbor'], + 'application/ccxml+xml' => ['ccxml'], + 'application/cdfx+xml' => ['cdfx'], + 'application/cdmi-capability' => ['cdmia'], + 'application/cdmi-container' => ['cdmic'], + 'application/cdmi-domain' => ['cdmid'], + 'application/cdmi-object' => ['cdmio'], + 'application/cdmi-queue' => ['cdmiq'], + 'application/cdr' => ['cdr'], + 'application/coreldraw' => ['cdr'], + 'application/cpl+xml' => ['cpl'], + 'application/csv' => ['csv'], + 'application/cu-seeme' => ['cu'], + 'application/dash+xml' => ['mpd'], + 'application/dash-patch+xml' => ['mpp'], + 'application/davmount+xml' => ['davmount'], + 'application/dbase' => ['dbf'], + 'application/dbf' => ['dbf'], + 'application/dicom' => ['dcm'], + 'application/docbook+xml' => ['dbk', 'docbook'], + 'application/dssc+der' => ['dssc'], + 'application/dssc+xml' => ['xdssc'], + 'application/ecmascript' => ['ecma', 'es'], + 'application/emf' => ['emf'], + 'application/emma+xml' => ['emma'], + 'application/emotionml+xml' => ['emotionml'], + 'application/epub+zip' => ['epub'], + 'application/exi' => ['exi'], + 'application/express' => ['exp'], + 'application/fdt+xml' => ['fdt'], + 'application/fits' => ['fits', 'fit', 'fts'], + 'application/font-tdpfr' => ['pfr'], + 'application/font-woff' => ['woff'], + 'application/futuresplash' => ['swf', 'spl'], + 'application/geo+json' => ['geojson', 'geo.json'], + 'application/gml+xml' => ['gml'], + 'application/gnunet-directory' => ['gnd'], + 'application/gpx' => ['gpx'], + 'application/gpx+xml' => ['gpx'], + 'application/gxf' => ['gxf'], + 'application/gzip' => ['gz'], + 'application/hjson' => ['hjson'], + 'application/hyperstudio' => ['stk'], + 'application/ico' => ['ico'], + 'application/ics' => ['vcs', 'ics'], + 'application/illustrator' => ['ai'], + 'application/inkml+xml' => ['ink', 'inkml'], + 'application/ipfix' => ['ipfix'], + 'application/its+xml' => ['its'], + 'application/java' => ['class'], + 'application/java-archive' => ['jar', 'war', 'ear'], + 'application/java-byte-code' => ['class'], + 'application/java-serialized-object' => ['ser'], + 'application/java-vm' => ['class'], + 'application/javascript' => ['js', 'mjs', 'jsm'], + 'application/jrd+json' => ['jrd'], + 'application/json' => ['json', 'map'], + 'application/json-patch+json' => ['json-patch'], + 'application/json5' => ['json5'], + 'application/jsonml+json' => ['jsonml'], + 'application/ld+json' => ['jsonld'], + 'application/lgr+xml' => ['lgr'], + 'application/lost+xml' => ['lostxml'], + 'application/lotus123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/m3u' => ['m3u', 'm3u8', 'vlc'], + 'application/mac-binhex40' => ['hqx'], + 'application/mac-compactpro' => ['cpt'], + 'application/mads+xml' => ['mads'], + 'application/manifest+json' => ['webmanifest'], + 'application/marc' => ['mrc'], + 'application/marcxml+xml' => ['mrcx'], + 'application/mathematica' => ['ma', 'nb', 'mb'], + 'application/mathml+xml' => ['mathml', 'mml'], + 'application/mbox' => ['mbox'], + 'application/mdb' => ['mdb'], + 'application/media-policy-dataset+xml' => ['mpf'], + 'application/mediaservercontrol+xml' => ['mscml'], + 'application/metalink+xml' => ['metalink'], + 'application/metalink4+xml' => ['meta4'], + 'application/mets+xml' => ['mets'], + 'application/mmt-aei+xml' => ['maei'], + 'application/mmt-usd+xml' => ['musd'], + 'application/mods+xml' => ['mods'], + 'application/mp21' => ['m21', 'mp21'], + 'application/mp4' => ['mp4s', 'm4p'], + 'application/mrb-consumer+xml' => ['xdf'], + 'application/mrb-publish+xml' => ['xdf'], + 'application/ms-tnef' => ['tnef', 'tnf'], + 'application/msaccess' => ['mdb'], + 'application/msexcel' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'], + 'application/mspowerpoint' => ['ppz', 'ppt', 'pps', 'pot'], + 'application/msword' => ['doc', 'dot'], + 'application/msword-template' => ['dot'], + 'application/mxf' => ['mxf'], + 'application/n-quads' => ['nq'], + 'application/n-triples' => ['nt'], + 'application/nappdf' => ['pdf'], + 'application/node' => ['cjs'], + 'application/octet-stream' => ['bin', 'dms', 'lrf', 'mar', 'so', 'dist', 'distz', 'pkg', 'bpk', 'dump', 'elc', 'deploy', 'exe', 'dll', 'deb', 'dmg', 'iso', 'img', 'msi', 'msp', 'msm', 'buffer'], + 'application/oda' => ['oda'], + 'application/oebps-package+xml' => ['opf'], + 'application/ogg' => ['ogx'], + 'application/omdoc+xml' => ['omdoc'], + 'application/onenote' => ['onetoc', 'onetoc2', 'onetmp', 'onepkg'], + 'application/ovf' => ['ova'], + 'application/owl+xml' => ['owx'], + 'application/oxps' => ['oxps'], + 'application/p2p-overlay+xml' => ['relo'], + 'application/patch-ops-error+xml' => ['xer'], + 'application/pcap' => ['pcap', 'cap', 'dmp'], + 'application/pdf' => ['pdf'], + 'application/pgp' => ['pgp', 'gpg', 'asc'], + 'application/pgp-encrypted' => ['pgp', 'gpg', 'asc'], + 'application/pgp-keys' => ['asc', 'skr', 'pkr', 'pgp', 'gpg', 'key'], + 'application/pgp-signature' => ['asc', 'sig', 'pgp', 'gpg'], + 'application/photoshop' => ['psd'], + 'application/pics-rules' => ['prf'], + 'application/pkcs10' => ['p10'], + 'application/pkcs12' => ['p12', 'pfx'], + 'application/pkcs7-mime' => ['p7m', 'p7c'], + 'application/pkcs7-signature' => ['p7s'], + 'application/pkcs8' => ['p8'], + 'application/pkcs8-encrypted' => ['p8e'], + 'application/pkix-attr-cert' => ['ac'], + 'application/pkix-cert' => ['cer'], + 'application/pkix-crl' => ['crl'], + 'application/pkix-pkipath' => ['pkipath'], + 'application/pkixcmp' => ['pki'], + 'application/pls' => ['pls'], + 'application/pls+xml' => ['pls'], + 'application/postscript' => ['ai', 'eps', 'ps'], + 'application/powerpoint' => ['ppz', 'ppt', 'pps', 'pot'], + 'application/provenance+xml' => ['provx'], + 'application/prs.cww' => ['cww'], + 'application/pskc+xml' => ['pskcxml'], + 'application/ram' => ['ram'], + 'application/raml+yaml' => ['raml'], + 'application/rdf+xml' => ['rdf', 'owl', 'rdfs'], + 'application/reginfo+xml' => ['rif'], + 'application/relax-ng-compact-syntax' => ['rnc'], + 'application/resource-lists+xml' => ['rl'], + 'application/resource-lists-diff+xml' => ['rld'], + 'application/rls-services+xml' => ['rs'], + 'application/route-apd+xml' => ['rapd'], + 'application/route-s-tsid+xml' => ['sls'], + 'application/route-usd+xml' => ['rusd'], + 'application/rpki-ghostbusters' => ['gbr'], + 'application/rpki-manifest' => ['mft'], + 'application/rpki-roa' => ['roa'], + 'application/rsd+xml' => ['rsd'], + 'application/rss+xml' => ['rss'], + 'application/rtf' => ['rtf'], + 'application/sbml+xml' => ['sbml'], + 'application/schema+json' => ['json'], + 'application/scvp-cv-request' => ['scq'], + 'application/scvp-cv-response' => ['scs'], + 'application/scvp-vp-request' => ['spq'], + 'application/scvp-vp-response' => ['spp'], + 'application/sdp' => ['sdp'], + 'application/senml+xml' => ['senmlx'], + 'application/sensml+xml' => ['sensmlx'], + 'application/set-payment-initiation' => ['setpay'], + 'application/set-registration-initiation' => ['setreg'], + 'application/shf+xml' => ['shf'], + 'application/sieve' => ['siv', 'sieve'], + 'application/smil' => ['smil', 'smi', 'sml', 'kino'], + 'application/smil+xml' => ['smi', 'smil', 'sml', 'kino'], + 'application/sparql-query' => ['rq', 'qs'], + 'application/sparql-results+xml' => ['srx'], + 'application/sql' => ['sql'], + 'application/srgs' => ['gram'], + 'application/srgs+xml' => ['grxml'], + 'application/sru+xml' => ['sru'], + 'application/ssdl+xml' => ['ssdl'], + 'application/ssml+xml' => ['ssml'], + 'application/stuffit' => ['sit', 'hqx'], + 'application/swid+xml' => ['swidtag'], + 'application/tei+xml' => ['tei', 'teicorpus'], + 'application/tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'application/thraud+xml' => ['tfi'], + 'application/timestamped-data' => ['tsd'], + 'application/toml' => ['toml'], + 'application/trig' => ['trig'], + 'application/ttml+xml' => ['ttml'], + 'application/ubjson' => ['ubj'], + 'application/urc-ressheet+xml' => ['rsheet'], + 'application/urc-targetdesc+xml' => ['td'], + 'application/vnd.1000minds.decision-model+xml' => ['1km'], + 'application/vnd.3gpp.pic-bw-large' => ['plb'], + 'application/vnd.3gpp.pic-bw-small' => ['psb'], + 'application/vnd.3gpp.pic-bw-var' => ['pvb'], + 'application/vnd.3gpp2.tcap' => ['tcap'], + 'application/vnd.3m.post-it-notes' => ['pwn'], + 'application/vnd.accpac.simply.aso' => ['aso'], + 'application/vnd.accpac.simply.imp' => ['imp'], + 'application/vnd.acucobol' => ['acu'], + 'application/vnd.acucorp' => ['atc', 'acutc'], + 'application/vnd.adobe.air-application-installer-package+zip' => ['air'], + 'application/vnd.adobe.flash.movie' => ['swf', 'spl'], + 'application/vnd.adobe.formscentral.fcdt' => ['fcdt'], + 'application/vnd.adobe.fxp' => ['fxp', 'fxpl'], + 'application/vnd.adobe.illustrator' => ['ai'], + 'application/vnd.adobe.xdp+xml' => ['xdp'], + 'application/vnd.adobe.xfdf' => ['xfdf'], + 'application/vnd.age' => ['age'], + 'application/vnd.ahead.space' => ['ahead'], + 'application/vnd.airzip.filesecure.azf' => ['azf'], + 'application/vnd.airzip.filesecure.azs' => ['azs'], + 'application/vnd.amazon.ebook' => ['azw'], + 'application/vnd.amazon.mobi8-ebook' => ['azw3', 'kfx'], + 'application/vnd.americandynamics.acc' => ['acc'], + 'application/vnd.amiga.ami' => ['ami'], + 'application/vnd.android.package-archive' => ['apk'], + 'application/vnd.anser-web-certificate-issue-initiation' => ['cii'], + 'application/vnd.anser-web-funds-transfer-initiation' => ['fti'], + 'application/vnd.antix.game-component' => ['atx'], + 'application/vnd.appimage' => ['appimage'], + 'application/vnd.apple.installer+xml' => ['mpkg'], + 'application/vnd.apple.keynote' => ['key', 'keynote'], + 'application/vnd.apple.mpegurl' => ['m3u8', 'm3u'], + 'application/vnd.apple.numbers' => ['numbers'], + 'application/vnd.apple.pages' => ['pages'], + 'application/vnd.apple.pkpass' => ['pkpass'], + 'application/vnd.aristanetworks.swi' => ['swi'], + 'application/vnd.astraea-software.iota' => ['iota'], + 'application/vnd.audiograph' => ['aep'], + 'application/vnd.balsamiq.bmml+xml' => ['bmml'], + 'application/vnd.blueice.multipass' => ['mpm'], + 'application/vnd.bmi' => ['bmi'], + 'application/vnd.businessobjects' => ['rep'], + 'application/vnd.chemdraw+xml' => ['cdxml'], + 'application/vnd.chess-pgn' => ['pgn'], + 'application/vnd.chipnuts.karaoke-mmd' => ['mmd'], + 'application/vnd.cinderella' => ['cdy'], + 'application/vnd.citationstyles.style+xml' => ['csl'], + 'application/vnd.claymore' => ['cla'], + 'application/vnd.cloanto.rp9' => ['rp9'], + 'application/vnd.clonk.c4group' => ['c4g', 'c4d', 'c4f', 'c4p', 'c4u'], + 'application/vnd.cluetrust.cartomobile-config' => ['c11amc'], + 'application/vnd.cluetrust.cartomobile-config-pkg' => ['c11amz'], + 'application/vnd.coffeescript' => ['coffee'], + 'application/vnd.comicbook+zip' => ['cbz'], + 'application/vnd.comicbook-rar' => ['cbr'], + 'application/vnd.commonspace' => ['csp'], + 'application/vnd.contact.cmsg' => ['cdbcmsg'], + 'application/vnd.corel-draw' => ['cdr'], + 'application/vnd.cosmocaller' => ['cmc'], + 'application/vnd.crick.clicker' => ['clkx'], + 'application/vnd.crick.clicker.keyboard' => ['clkk'], + 'application/vnd.crick.clicker.palette' => ['clkp'], + 'application/vnd.crick.clicker.template' => ['clkt'], + 'application/vnd.crick.clicker.wordbank' => ['clkw'], + 'application/vnd.criticaltools.wbs+xml' => ['wbs'], + 'application/vnd.ctc-posml' => ['pml'], + 'application/vnd.cups-ppd' => ['ppd'], + 'application/vnd.curl.car' => ['car'], + 'application/vnd.curl.pcurl' => ['pcurl'], + 'application/vnd.dart' => ['dart'], + 'application/vnd.data-vision.rdz' => ['rdz'], + 'application/vnd.dbf' => ['dbf'], + 'application/vnd.debian.binary-package' => ['deb', 'udeb'], + 'application/vnd.dece.data' => ['uvf', 'uvvf', 'uvd', 'uvvd'], + 'application/vnd.dece.ttml+xml' => ['uvt', 'uvvt'], + 'application/vnd.dece.unspecified' => ['uvx', 'uvvx'], + 'application/vnd.dece.zip' => ['uvz', 'uvvz'], + 'application/vnd.denovo.fcselayout-link' => ['fe_launch'], + 'application/vnd.dna' => ['dna'], + 'application/vnd.dolby.mlp' => ['mlp'], + 'application/vnd.dpgraph' => ['dpg'], + 'application/vnd.dreamfactory' => ['dfac'], + 'application/vnd.ds-keypoint' => ['kpxx'], + 'application/vnd.dvb.ait' => ['ait'], + 'application/vnd.dvb.service' => ['svc'], + 'application/vnd.dynageo' => ['geo'], + 'application/vnd.ecowin.chart' => ['mag'], + 'application/vnd.efi.img' => ['raw-disk-image', 'img'], + 'application/vnd.efi.iso' => ['iso', 'iso9660'], + 'application/vnd.emusic-emusic_package' => ['emp'], + 'application/vnd.enliven' => ['nml'], + 'application/vnd.epson.esf' => ['esf'], + 'application/vnd.epson.msf' => ['msf'], + 'application/vnd.epson.quickanime' => ['qam'], + 'application/vnd.epson.salt' => ['slt'], + 'application/vnd.epson.ssf' => ['ssf'], + 'application/vnd.eszigno3+xml' => ['es3', 'et3'], + 'application/vnd.etsi.asic-e+zip' => ['asice'], + 'application/vnd.ezpix-album' => ['ez2'], + 'application/vnd.ezpix-package' => ['ez3'], + 'application/vnd.fdf' => ['fdf'], + 'application/vnd.fdsn.mseed' => ['mseed'], + 'application/vnd.fdsn.seed' => ['seed', 'dataless'], + 'application/vnd.flatpak' => ['flatpak', 'xdgapp'], + 'application/vnd.flatpak.ref' => ['flatpakref'], + 'application/vnd.flatpak.repo' => ['flatpakrepo'], + 'application/vnd.flographit' => ['gph'], + 'application/vnd.fluxtime.clip' => ['ftc'], + 'application/vnd.framemaker' => ['fm', 'frame', 'maker', 'book'], + 'application/vnd.frogans.fnc' => ['fnc'], + 'application/vnd.frogans.ltf' => ['ltf'], + 'application/vnd.fsc.weblaunch' => ['fsc'], + 'application/vnd.fujitsu.oasys' => ['oas'], + 'application/vnd.fujitsu.oasys2' => ['oa2'], + 'application/vnd.fujitsu.oasys3' => ['oa3'], + 'application/vnd.fujitsu.oasysgp' => ['fg5'], + 'application/vnd.fujitsu.oasysprs' => ['bh2'], + 'application/vnd.fujixerox.ddd' => ['ddd'], + 'application/vnd.fujixerox.docuworks' => ['xdw'], + 'application/vnd.fujixerox.docuworks.binder' => ['xbd'], + 'application/vnd.fuzzysheet' => ['fzs'], + 'application/vnd.genomatix.tuxedo' => ['txd'], + 'application/vnd.geo+json' => ['geojson', 'geo.json'], + 'application/vnd.geogebra.file' => ['ggb'], + 'application/vnd.geogebra.tool' => ['ggt'], + 'application/vnd.geometry-explorer' => ['gex', 'gre'], + 'application/vnd.geonext' => ['gxt'], + 'application/vnd.geoplan' => ['g2w'], + 'application/vnd.geospace' => ['g3w'], + 'application/vnd.gerber' => ['gbr'], + 'application/vnd.gmx' => ['gmx'], + 'application/vnd.google-apps.document' => ['gdoc'], + 'application/vnd.google-apps.presentation' => ['gslides'], + 'application/vnd.google-apps.spreadsheet' => ['gsheet'], + 'application/vnd.google-earth.kml+xml' => ['kml'], + 'application/vnd.google-earth.kmz' => ['kmz'], + 'application/vnd.grafeq' => ['gqf', 'gqs'], + 'application/vnd.groove-account' => ['gac'], + 'application/vnd.groove-help' => ['ghf'], + 'application/vnd.groove-identity-message' => ['gim'], + 'application/vnd.groove-injector' => ['grv'], + 'application/vnd.groove-tool-message' => ['gtm'], + 'application/vnd.groove-tool-template' => ['tpl'], + 'application/vnd.groove-vcard' => ['vcg'], + 'application/vnd.haansoft-hwp' => ['hwp'], + 'application/vnd.haansoft-hwt' => ['hwt'], + 'application/vnd.hal+xml' => ['hal'], + 'application/vnd.handheld-entertainment+xml' => ['zmm'], + 'application/vnd.hbci' => ['hbci'], + 'application/vnd.hhe.lesson-player' => ['les'], + 'application/vnd.hp-hpgl' => ['hpgl'], + 'application/vnd.hp-hpid' => ['hpid'], + 'application/vnd.hp-hps' => ['hps'], + 'application/vnd.hp-jlyt' => ['jlt'], + 'application/vnd.hp-pcl' => ['pcl'], + 'application/vnd.hp-pclxl' => ['pclxl'], + 'application/vnd.hydrostatix.sof-data' => ['sfd-hdstx'], + 'application/vnd.ibm.minipay' => ['mpy'], + 'application/vnd.ibm.modcap' => ['afp', 'listafp', 'list3820'], + 'application/vnd.ibm.rights-management' => ['irm'], + 'application/vnd.ibm.secure-container' => ['sc'], + 'application/vnd.iccprofile' => ['icc', 'icm'], + 'application/vnd.igloader' => ['igl'], + 'application/vnd.immervision-ivp' => ['ivp'], + 'application/vnd.immervision-ivu' => ['ivu'], + 'application/vnd.insors.igm' => ['igm'], + 'application/vnd.intercon.formnet' => ['xpw', 'xpx'], + 'application/vnd.intergeo' => ['i2g'], + 'application/vnd.intu.qbo' => ['qbo'], + 'application/vnd.intu.qfx' => ['qfx'], + 'application/vnd.ipunplugged.rcprofile' => ['rcprofile'], + 'application/vnd.irepository.package+xml' => ['irp'], + 'application/vnd.is-xpr' => ['xpr'], + 'application/vnd.isac.fcs' => ['fcs'], + 'application/vnd.jam' => ['jam'], + 'application/vnd.jcp.javame.midlet-rms' => ['rms'], + 'application/vnd.jisp' => ['jisp'], + 'application/vnd.joost.joda-archive' => ['joda'], + 'application/vnd.kahootz' => ['ktz', 'ktr'], + 'application/vnd.kde.karbon' => ['karbon'], + 'application/vnd.kde.kchart' => ['chrt'], + 'application/vnd.kde.kformula' => ['kfo'], + 'application/vnd.kde.kivio' => ['flw'], + 'application/vnd.kde.kontour' => ['kon'], + 'application/vnd.kde.kpresenter' => ['kpr', 'kpt'], + 'application/vnd.kde.kspread' => ['ksp'], + 'application/vnd.kde.kword' => ['kwd', 'kwt'], + 'application/vnd.kenameaapp' => ['htke'], + 'application/vnd.kidspiration' => ['kia'], + 'application/vnd.kinar' => ['kne', 'knp'], + 'application/vnd.koan' => ['skp', 'skd', 'skt', 'skm'], + 'application/vnd.kodak-descriptor' => ['sse'], + 'application/vnd.las.las+xml' => ['lasxml'], + 'application/vnd.llamagraphics.life-balance.desktop' => ['lbd'], + 'application/vnd.llamagraphics.life-balance.exchange+xml' => ['lbe'], + 'application/vnd.lotus-1-2-3' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/vnd.lotus-approach' => ['apr'], + 'application/vnd.lotus-freelance' => ['pre'], + 'application/vnd.lotus-notes' => ['nsf'], + 'application/vnd.lotus-organizer' => ['org'], + 'application/vnd.lotus-screencam' => ['scm'], + 'application/vnd.lotus-wordpro' => ['lwp'], + 'application/vnd.macports.portpkg' => ['portpkg'], + 'application/vnd.mapbox-vector-tile' => ['mvt'], + 'application/vnd.mcd' => ['mcd'], + 'application/vnd.medcalcdata' => ['mc1'], + 'application/vnd.mediastation.cdkey' => ['cdkey'], + 'application/vnd.mfer' => ['mwf'], + 'application/vnd.mfmp' => ['mfm'], + 'application/vnd.micrografx.flo' => ['flo'], + 'application/vnd.micrografx.igx' => ['igx'], + 'application/vnd.mif' => ['mif'], + 'application/vnd.mobius.daf' => ['daf'], + 'application/vnd.mobius.dis' => ['dis'], + 'application/vnd.mobius.mbk' => ['mbk'], + 'application/vnd.mobius.mqy' => ['mqy'], + 'application/vnd.mobius.msl' => ['msl'], + 'application/vnd.mobius.plc' => ['plc'], + 'application/vnd.mobius.txf' => ['txf'], + 'application/vnd.mophun.application' => ['mpn'], + 'application/vnd.mophun.certificate' => ['mpc'], + 'application/vnd.mozilla.xul+xml' => ['xul'], + 'application/vnd.ms-3mfdocument' => ['3mf'], + 'application/vnd.ms-access' => ['mdb'], + 'application/vnd.ms-artgalry' => ['cil'], + 'application/vnd.ms-asf' => ['asf'], + 'application/vnd.ms-cab-compressed' => ['cab'], + 'application/vnd.ms-excel' => ['xls', 'xlm', 'xla', 'xlc', 'xlt', 'xlw', 'xll', 'xld'], + 'application/vnd.ms-excel.addin.macroenabled.12' => ['xlam'], + 'application/vnd.ms-excel.sheet.binary.macroenabled.12' => ['xlsb'], + 'application/vnd.ms-excel.sheet.macroenabled.12' => ['xlsm'], + 'application/vnd.ms-excel.template.macroenabled.12' => ['xltm'], + 'application/vnd.ms-fontobject' => ['eot'], + 'application/vnd.ms-htmlhelp' => ['chm'], + 'application/vnd.ms-ims' => ['ims'], + 'application/vnd.ms-lrm' => ['lrm'], + 'application/vnd.ms-officetheme' => ['thmx'], + 'application/vnd.ms-outlook' => ['msg'], + 'application/vnd.ms-pki.seccat' => ['cat'], + 'application/vnd.ms-pki.stl' => ['stl'], + 'application/vnd.ms-powerpoint' => ['ppt', 'pps', 'pot', 'ppz'], + 'application/vnd.ms-powerpoint.addin.macroenabled.12' => ['ppam'], + 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => ['pptm'], + 'application/vnd.ms-powerpoint.slide.macroenabled.12' => ['sldm'], + 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => ['ppsm'], + 'application/vnd.ms-powerpoint.template.macroenabled.12' => ['potm'], + 'application/vnd.ms-project' => ['mpp', 'mpt'], + 'application/vnd.ms-publisher' => ['pub'], + 'application/vnd.ms-tnef' => ['tnef', 'tnf'], + 'application/vnd.ms-visio.drawing.macroenabled.main+xml' => ['vsdm'], + 'application/vnd.ms-visio.drawing.main+xml' => ['vsdx'], + 'application/vnd.ms-visio.stencil.macroenabled.main+xml' => ['vssm'], + 'application/vnd.ms-visio.stencil.main+xml' => ['vssx'], + 'application/vnd.ms-visio.template.macroenabled.main+xml' => ['vstm'], + 'application/vnd.ms-visio.template.main+xml' => ['vstx'], + 'application/vnd.ms-word' => ['doc'], + 'application/vnd.ms-word.document.macroenabled.12' => ['docm'], + 'application/vnd.ms-word.template.macroenabled.12' => ['dotm'], + 'application/vnd.ms-works' => ['wps', 'wks', 'wcm', 'wdb', 'xlr'], + 'application/vnd.ms-wpl' => ['wpl'], + 'application/vnd.ms-xpsdocument' => ['xps'], + 'application/vnd.msaccess' => ['mdb'], + 'application/vnd.mseq' => ['mseq'], + 'application/vnd.musician' => ['mus'], + 'application/vnd.muvee.style' => ['msty'], + 'application/vnd.mynfc' => ['taglet'], + 'application/vnd.neurolanguage.nlu' => ['nlu'], + 'application/vnd.nintendo.snes.rom' => ['sfc', 'smc'], + 'application/vnd.nitf' => ['ntf', 'nitf'], + 'application/vnd.noblenet-directory' => ['nnd'], + 'application/vnd.noblenet-sealer' => ['nns'], + 'application/vnd.noblenet-web' => ['nnw'], + 'application/vnd.nokia.n-gage.ac+xml' => ['ac'], + 'application/vnd.nokia.n-gage.data' => ['ngdat'], + 'application/vnd.nokia.n-gage.symbian.install' => ['n-gage'], + 'application/vnd.nokia.radio-preset' => ['rpst'], + 'application/vnd.nokia.radio-presets' => ['rpss'], + 'application/vnd.novadigm.edm' => ['edm'], + 'application/vnd.novadigm.edx' => ['edx'], + 'application/vnd.novadigm.ext' => ['ext'], + 'application/vnd.oasis.docbook+xml' => ['dbk', 'docbook'], + 'application/vnd.oasis.opendocument.chart' => ['odc'], + 'application/vnd.oasis.opendocument.chart-template' => ['otc'], + 'application/vnd.oasis.opendocument.database' => ['odb'], + 'application/vnd.oasis.opendocument.formula' => ['odf'], + 'application/vnd.oasis.opendocument.formula-template' => ['odft', 'otf'], + 'application/vnd.oasis.opendocument.graphics' => ['odg'], + 'application/vnd.oasis.opendocument.graphics-flat-xml' => ['fodg'], + 'application/vnd.oasis.opendocument.graphics-template' => ['otg'], + 'application/vnd.oasis.opendocument.image' => ['odi'], + 'application/vnd.oasis.opendocument.image-template' => ['oti'], + 'application/vnd.oasis.opendocument.presentation' => ['odp'], + 'application/vnd.oasis.opendocument.presentation-flat-xml' => ['fodp'], + 'application/vnd.oasis.opendocument.presentation-template' => ['otp'], + 'application/vnd.oasis.opendocument.spreadsheet' => ['ods'], + 'application/vnd.oasis.opendocument.spreadsheet-flat-xml' => ['fods'], + 'application/vnd.oasis.opendocument.spreadsheet-template' => ['ots'], + 'application/vnd.oasis.opendocument.text' => ['odt'], + 'application/vnd.oasis.opendocument.text-flat-xml' => ['fodt'], + 'application/vnd.oasis.opendocument.text-master' => ['odm'], + 'application/vnd.oasis.opendocument.text-template' => ['ott'], + 'application/vnd.oasis.opendocument.text-web' => ['oth'], + 'application/vnd.olpc-sugar' => ['xo'], + 'application/vnd.oma.dd2+xml' => ['dd2'], + 'application/vnd.openblox.game+xml' => ['obgx'], + 'application/vnd.openofficeorg.extension' => ['oxt'], + 'application/vnd.openstreetmap.data+xml' => ['osm'], + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => ['pptx'], + 'application/vnd.openxmlformats-officedocument.presentationml.slide' => ['sldx'], + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => ['ppsx'], + 'application/vnd.openxmlformats-officedocument.presentationml.template' => ['potx'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => ['xlsx'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => ['xltx'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => ['docx'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => ['dotx'], + 'application/vnd.osgeo.mapguide.package' => ['mgp'], + 'application/vnd.osgi.dp' => ['dp'], + 'application/vnd.osgi.subsystem' => ['esa'], + 'application/vnd.palm' => ['pdb', 'pqa', 'oprc', 'prc'], + 'application/vnd.pawaafile' => ['paw'], + 'application/vnd.pg.format' => ['str'], + 'application/vnd.pg.osasli' => ['ei6'], + 'application/vnd.picsel' => ['efif'], + 'application/vnd.pmi.widget' => ['wg'], + 'application/vnd.pocketlearn' => ['plf'], + 'application/vnd.powerbuilder6' => ['pbd'], + 'application/vnd.previewsystems.box' => ['box'], + 'application/vnd.proteus.magazine' => ['mgz'], + 'application/vnd.publishare-delta-tree' => ['qps'], + 'application/vnd.pvi.ptid1' => ['ptid'], + 'application/vnd.quark.quarkxpress' => ['qxd', 'qxt', 'qwd', 'qwt', 'qxl', 'qxb'], + 'application/vnd.rar' => ['rar'], + 'application/vnd.realvnc.bed' => ['bed'], + 'application/vnd.recordare.musicxml' => ['mxl'], + 'application/vnd.recordare.musicxml+xml' => ['musicxml'], + 'application/vnd.rig.cryptonote' => ['cryptonote'], + 'application/vnd.rim.cod' => ['cod'], + 'application/vnd.rn-realmedia' => ['rm', 'rmj', 'rmm', 'rms', 'rmx', 'rmvb'], + 'application/vnd.rn-realmedia-vbr' => ['rmvb', 'rm', 'rmj', 'rmm', 'rms', 'rmx'], + 'application/vnd.route66.link66+xml' => ['link66'], + 'application/vnd.sailingtracker.track' => ['st'], + 'application/vnd.sdp' => ['sdp'], + 'application/vnd.seemail' => ['see'], + 'application/vnd.sema' => ['sema'], + 'application/vnd.semd' => ['semd'], + 'application/vnd.semf' => ['semf'], + 'application/vnd.shana.informed.formdata' => ['ifm'], + 'application/vnd.shana.informed.formtemplate' => ['itp'], + 'application/vnd.shana.informed.interchange' => ['iif'], + 'application/vnd.shana.informed.package' => ['ipk'], + 'application/vnd.simtech-mindmapper' => ['twd', 'twds'], + 'application/vnd.smaf' => ['mmf', 'smaf'], + 'application/vnd.smart.teacher' => ['teacher'], + 'application/vnd.snap' => ['snap'], + 'application/vnd.software602.filler.form+xml' => ['fo'], + 'application/vnd.solent.sdkm+xml' => ['sdkm', 'sdkd'], + 'application/vnd.spotfire.dxp' => ['dxp'], + 'application/vnd.spotfire.sfs' => ['sfs'], + 'application/vnd.sqlite3' => ['sqlite3'], + 'application/vnd.squashfs' => ['sqsh'], + 'application/vnd.stardivision.calc' => ['sdc'], + 'application/vnd.stardivision.chart' => ['sds'], + 'application/vnd.stardivision.draw' => ['sda'], + 'application/vnd.stardivision.impress' => ['sdd', 'sdp'], + 'application/vnd.stardivision.mail' => ['smd'], + 'application/vnd.stardivision.math' => ['smf'], + 'application/vnd.stardivision.writer' => ['sdw', 'vor', 'sgl'], + 'application/vnd.stardivision.writer-global' => ['sgl', 'sdw', 'vor'], + 'application/vnd.stepmania.package' => ['smzip'], + 'application/vnd.stepmania.stepchart' => ['sm'], + 'application/vnd.sun.wadl+xml' => ['wadl'], + 'application/vnd.sun.xml.base' => ['odb'], + 'application/vnd.sun.xml.calc' => ['sxc'], + 'application/vnd.sun.xml.calc.template' => ['stc'], + 'application/vnd.sun.xml.draw' => ['sxd'], + 'application/vnd.sun.xml.draw.template' => ['std'], + 'application/vnd.sun.xml.impress' => ['sxi'], + 'application/vnd.sun.xml.impress.template' => ['sti'], + 'application/vnd.sun.xml.math' => ['sxm'], + 'application/vnd.sun.xml.writer' => ['sxw'], + 'application/vnd.sun.xml.writer.global' => ['sxg'], + 'application/vnd.sun.xml.writer.template' => ['stw'], + 'application/vnd.sus-calendar' => ['sus', 'susp'], + 'application/vnd.svd' => ['svd'], + 'application/vnd.symbian.install' => ['sis', 'sisx'], + 'application/vnd.syncml+xml' => ['xsm'], + 'application/vnd.syncml.dm+wbxml' => ['bdm'], + 'application/vnd.syncml.dm+xml' => ['xdm'], + 'application/vnd.syncml.dmddf+xml' => ['ddf'], + 'application/vnd.tao.intent-module-archive' => ['tao'], + 'application/vnd.tcpdump.pcap' => ['pcap', 'cap', 'dmp'], + 'application/vnd.tmobile-livetv' => ['tmo'], + 'application/vnd.trid.tpt' => ['tpt'], + 'application/vnd.triscape.mxs' => ['mxs'], + 'application/vnd.trueapp' => ['tra'], + 'application/vnd.truedoc' => ['pfr'], + 'application/vnd.ufdl' => ['ufd', 'ufdl'], + 'application/vnd.uiq.theme' => ['utz'], + 'application/vnd.umajin' => ['umj'], + 'application/vnd.unity' => ['unityweb'], + 'application/vnd.uoml+xml' => ['uoml'], + 'application/vnd.vcx' => ['vcx'], + 'application/vnd.visio' => ['vsd', 'vst', 'vss', 'vsw'], + 'application/vnd.visionary' => ['vis'], + 'application/vnd.vsf' => ['vsf'], + 'application/vnd.wap.wbxml' => ['wbxml'], + 'application/vnd.wap.wmlc' => ['wmlc'], + 'application/vnd.wap.wmlscriptc' => ['wmlsc'], + 'application/vnd.webturbo' => ['wtb'], + 'application/vnd.wolfram.player' => ['nbp'], + 'application/vnd.wordperfect' => ['wpd', 'wp', 'wp4', 'wp5', 'wp6', 'wpp'], + 'application/vnd.wqd' => ['wqd'], + 'application/vnd.wt.stf' => ['stf'], + 'application/vnd.xara' => ['xar'], + 'application/vnd.xdgapp' => ['flatpak', 'xdgapp'], + 'application/vnd.xfdl' => ['xfdl'], + 'application/vnd.yamaha.hv-dic' => ['hvd'], + 'application/vnd.yamaha.hv-script' => ['hvs'], + 'application/vnd.yamaha.hv-voice' => ['hvp'], + 'application/vnd.yamaha.openscoreformat' => ['osf'], + 'application/vnd.yamaha.openscoreformat.osfpvg+xml' => ['osfpvg'], + 'application/vnd.yamaha.smaf-audio' => ['saf'], + 'application/vnd.yamaha.smaf-phrase' => ['spf'], + 'application/vnd.yellowriver-custom-menu' => ['cmp'], + 'application/vnd.youtube.yt' => ['yt'], + 'application/vnd.zul' => ['zir', 'zirz'], + 'application/vnd.zzazz.deck+xml' => ['zaz'], + 'application/voicexml+xml' => ['vxml'], + 'application/wasm' => ['wasm'], + 'application/watcherinfo+xml' => ['wif'], + 'application/widget' => ['wgt'], + 'application/winhlp' => ['hlp'], + 'application/wk1' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/wmf' => ['wmf'], + 'application/wordperfect' => ['wp', 'wp4', 'wp5', 'wp6', 'wpd', 'wpp'], + 'application/wsdl+xml' => ['wsdl'], + 'application/wspolicy+xml' => ['wspolicy'], + 'application/wwf' => ['wwf'], + 'application/x-123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/x-7z-compressed' => ['7z', '7z.001'], + 'application/x-abiword' => ['abw', 'abw.CRASHED', 'abw.gz', 'zabw'], + 'application/x-ace' => ['ace'], + 'application/x-ace-compressed' => ['ace'], + 'application/x-alz' => ['alz'], + 'application/x-amiga-disk-format' => ['adf'], + 'application/x-amipro' => ['sam'], + 'application/x-annodex' => ['anx'], + 'application/x-aportisdoc' => ['pdb', 'pdc'], + 'application/x-apple-diskimage' => ['dmg'], + 'application/x-apple-systemprofiler+xml' => ['spx'], + 'application/x-appleworks-document' => ['cwk'], + 'application/x-applix-spreadsheet' => ['as'], + 'application/x-applix-word' => ['aw'], + 'application/x-archive' => ['a', 'ar'], + 'application/x-arj' => ['arj'], + 'application/x-asar' => ['asar'], + 'application/x-asp' => ['asp'], + 'application/x-atari-2600-rom' => ['a26'], + 'application/x-atari-7800-rom' => ['a78'], + 'application/x-atari-lynx-rom' => ['lnx'], + 'application/x-authorware-bin' => ['aab', 'x32', 'u32', 'vox'], + 'application/x-authorware-map' => ['aam'], + 'application/x-authorware-seg' => ['aas'], + 'application/x-awk' => ['awk'], + 'application/x-bat' => ['bat'], + 'application/x-bcpio' => ['bcpio'], + 'application/x-bdoc' => ['bdoc'], + 'application/x-bittorrent' => ['torrent'], + 'application/x-blender' => ['blend', 'BLEND', 'blender'], + 'application/x-blorb' => ['blb', 'blorb'], + 'application/x-bps-patch' => ['bps'], + 'application/x-bsdiff' => ['bsdiff'], + 'application/x-bz2' => ['bz2'], + 'application/x-bzdvi' => ['dvi.bz2'], + 'application/x-bzip' => ['bz'], + 'application/x-bzip-compressed-tar' => ['tar.bz', 'tbz', 'tbz2', 'tb2'], + 'application/x-bzip2' => ['bz2', 'boz'], + 'application/x-bzip2-compressed-tar' => ['tar.bz2', 'tbz2', 'tb2'], + 'application/x-bzip3' => ['bz3'], + 'application/x-bzip3-compressed-tar' => ['tar.bz3', 'tbz3'], + 'application/x-bzpdf' => ['pdf.bz2'], + 'application/x-bzpostscript' => ['ps.bz2'], + 'application/x-cb7' => ['cb7'], + 'application/x-cbr' => ['cbr', 'cba', 'cbt', 'cbz', 'cb7'], + 'application/x-cbt' => ['cbt'], + 'application/x-cbz' => ['cbz'], + 'application/x-ccmx' => ['ccmx'], + 'application/x-cd-image' => ['iso', 'iso9660'], + 'application/x-cdlink' => ['vcd'], + 'application/x-cdr' => ['cdr'], + 'application/x-cdrdao-toc' => ['toc'], + 'application/x-cfs-compressed' => ['cfs'], + 'application/x-chat' => ['chat'], + 'application/x-chess-pgn' => ['pgn'], + 'application/x-chm' => ['chm'], + 'application/x-chrome-extension' => ['crx'], + 'application/x-cisco-vpn-settings' => ['pcf'], + 'application/x-cocoa' => ['cco'], + 'application/x-compress' => ['Z'], + 'application/x-compressed-iso' => ['cso'], + 'application/x-compressed-tar' => ['tar.gz', 'tgz'], + 'application/x-conference' => ['nsc'], + 'application/x-coreldraw' => ['cdr'], + 'application/x-cpio' => ['cpio'], + 'application/x-cpio-compressed' => ['cpio.gz'], + 'application/x-csh' => ['csh'], + 'application/x-cue' => ['cue'], + 'application/x-dar' => ['dar'], + 'application/x-dbase' => ['dbf'], + 'application/x-dbf' => ['dbf'], + 'application/x-dc-rom' => ['dc'], + 'application/x-deb' => ['deb', 'udeb'], + 'application/x-debian-package' => ['deb', 'udeb'], + 'application/x-designer' => ['ui'], + 'application/x-desktop' => ['desktop', 'kdelnk'], + 'application/x-dgc-compressed' => ['dgc'], + 'application/x-dia-diagram' => ['dia'], + 'application/x-dia-shape' => ['shape'], + 'application/x-director' => ['dir', 'dcr', 'dxr', 'cst', 'cct', 'cxt', 'w3d', 'fgd', 'swa'], + 'application/x-discjuggler-cd-image' => ['cdi'], + 'application/x-docbook+xml' => ['dbk', 'docbook'], + 'application/x-doom' => ['wad'], + 'application/x-doom-wad' => ['wad'], + 'application/x-dreamcast-rom' => ['iso'], + 'application/x-dtbncx+xml' => ['ncx'], + 'application/x-dtbook+xml' => ['dtb'], + 'application/x-dtbresource+xml' => ['res'], + 'application/x-dvi' => ['dvi'], + 'application/x-e-theme' => ['etheme'], + 'application/x-egon' => ['egon'], + 'application/x-emf' => ['emf'], + 'application/x-envoy' => ['evy'], + 'application/x-eris-link+cbor' => ['eris'], + 'application/x-eva' => ['eva'], + 'application/x-excellon' => ['drl'], + 'application/x-fd-file' => ['fd', 'qd'], + 'application/x-fds-disk' => ['fds'], + 'application/x-fictionbook' => ['fb2'], + 'application/x-fictionbook+xml' => ['fb2'], + 'application/x-fishscript' => ['fish'], + 'application/x-flash-video' => ['flv'], + 'application/x-fluid' => ['fl'], + 'application/x-font-afm' => ['afm'], + 'application/x-font-bdf' => ['bdf'], + 'application/x-font-ghostscript' => ['gsf'], + 'application/x-font-linux-psf' => ['psf'], + 'application/x-font-otf' => ['otf'], + 'application/x-font-pcf' => ['pcf', 'pcf.Z', 'pcf.gz'], + 'application/x-font-snf' => ['snf'], + 'application/x-font-speedo' => ['spd'], + 'application/x-font-truetype' => ['ttf'], + 'application/x-font-ttf' => ['ttf'], + 'application/x-font-ttx' => ['ttx'], + 'application/x-font-type1' => ['pfa', 'pfb', 'pfm', 'afm', 'gsf'], + 'application/x-font-woff' => ['woff'], + 'application/x-frame' => ['fm'], + 'application/x-freearc' => ['arc'], + 'application/x-futuresplash' => ['spl'], + 'application/x-gameboy-color-rom' => ['gbc', 'cgb'], + 'application/x-gameboy-rom' => ['gb', 'sgb'], + 'application/x-gamecube-iso-image' => ['iso'], + 'application/x-gamecube-rom' => ['iso'], + 'application/x-gamegear-rom' => ['gg'], + 'application/x-gba-rom' => ['gba', 'agb'], + 'application/x-gca-compressed' => ['gca'], + 'application/x-gd-rom-cue' => ['gdi'], + 'application/x-gdscript' => ['gd'], + 'application/x-gedcom' => ['ged', 'gedcom'], + 'application/x-genesis-32x-rom' => ['32x', 'mdx'], + 'application/x-genesis-rom' => ['gen', 'smd', 'sgd'], + 'application/x-gerber' => ['gbr'], + 'application/x-gerber-job' => ['gbrjob'], + 'application/x-gettext' => ['po'], + 'application/x-gettext-translation' => ['gmo', 'mo'], + 'application/x-glade' => ['glade'], + 'application/x-glulx' => ['ulx'], + 'application/x-gnome-app-info' => ['desktop', 'kdelnk'], + 'application/x-gnucash' => ['gnucash', 'gnc', 'xac'], + 'application/x-gnumeric' => ['gnumeric'], + 'application/x-gnuplot' => ['gp', 'gplt', 'gnuplot'], + 'application/x-go-sgf' => ['sgf'], + 'application/x-godot-resource' => ['res', 'tres'], + 'application/x-godot-scene' => ['scn', 'tscn', 'escn'], + 'application/x-godot-shader' => ['gdshader'], + 'application/x-gpx' => ['gpx'], + 'application/x-gpx+xml' => ['gpx'], + 'application/x-gramps-xml' => ['gramps'], + 'application/x-graphite' => ['gra'], + 'application/x-gtar' => ['gtar', 'tar', 'gem'], + 'application/x-gtk-builder' => ['ui'], + 'application/x-gz-font-linux-psf' => ['psf.gz'], + 'application/x-gzdvi' => ['dvi.gz'], + 'application/x-gzip' => ['gz'], + 'application/x-gzpdf' => ['pdf.gz'], + 'application/x-gzpostscript' => ['ps.gz'], + 'application/x-hdf' => ['hdf', 'hdf4', 'h4', 'hdf5', 'h5'], + 'application/x-hfe-file' => ['hfe'], + 'application/x-hfe-floppy-image' => ['hfe'], + 'application/x-httpd-php' => ['php'], + 'application/x-hwp' => ['hwp'], + 'application/x-hwt' => ['hwt'], + 'application/x-ica' => ['ica'], + 'application/x-install-instructions' => ['install'], + 'application/x-ips-patch' => ['ips'], + 'application/x-ipynb+json' => ['ipynb'], + 'application/x-iso9660-appimage' => ['appimage'], + 'application/x-iso9660-image' => ['iso', 'iso9660'], + 'application/x-it87' => ['it87'], + 'application/x-iwork-keynote-sffkey' => ['key'], + 'application/x-iwork-numbers-sffnumbers' => ['numbers'], + 'application/x-iwork-pages-sffpages' => ['pages'], + 'application/x-jar' => ['jar'], + 'application/x-java' => ['class'], + 'application/x-java-archive' => ['jar'], + 'application/x-java-archive-diff' => ['jardiff'], + 'application/x-java-class' => ['class'], + 'application/x-java-jce-keystore' => ['jceks'], + 'application/x-java-jnlp-file' => ['jnlp'], + 'application/x-java-keystore' => ['jks', 'ks'], + 'application/x-java-pack200' => ['pack'], + 'application/x-java-vm' => ['class'], + 'application/x-javascript' => ['js', 'jsm', 'mjs'], + 'application/x-jbuilder-project' => ['jpr', 'jpx'], + 'application/x-karbon' => ['karbon'], + 'application/x-kchart' => ['chrt'], + 'application/x-keepass2' => ['kdbx'], + 'application/x-kexi-connectiondata' => ['kexic'], + 'application/x-kexiproject-shortcut' => ['kexis'], + 'application/x-kexiproject-sqlite' => ['kexi'], + 'application/x-kexiproject-sqlite2' => ['kexi'], + 'application/x-kexiproject-sqlite3' => ['kexi'], + 'application/x-kformula' => ['kfo'], + 'application/x-killustrator' => ['kil'], + 'application/x-kivio' => ['flw'], + 'application/x-kontour' => ['kon'], + 'application/x-kpovmodeler' => ['kpm'], + 'application/x-kpresenter' => ['kpr', 'kpt'], + 'application/x-krita' => ['kra', 'krz'], + 'application/x-kspread' => ['ksp'], + 'application/x-kugar' => ['kud'], + 'application/x-kword' => ['kwd', 'kwt'], + 'application/x-latex' => ['latex'], + 'application/x-lha' => ['lha', 'lzh'], + 'application/x-lhz' => ['lhz'], + 'application/x-linguist' => ['ts'], + 'application/x-lmdb' => ['mdb', 'lmdb'], + 'application/x-lotus123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'application/x-lrzip' => ['lrz'], + 'application/x-lrzip-compressed-tar' => ['tar.lrz', 'tlrz'], + 'application/x-lua-bytecode' => ['luac'], + 'application/x-lyx' => ['lyx'], + 'application/x-lz4' => ['lz4'], + 'application/x-lz4-compressed-tar' => ['tar.lz4'], + 'application/x-lzh-compressed' => ['lzh', 'lha'], + 'application/x-lzip' => ['lz'], + 'application/x-lzip-compressed-tar' => ['tar.lz'], + 'application/x-lzma' => ['lzma'], + 'application/x-lzma-compressed-tar' => ['tar.lzma', 'tlz'], + 'application/x-lzop' => ['lzo'], + 'application/x-lzpdf' => ['pdf.lz'], + 'application/x-m4' => ['m4'], + 'application/x-magicpoint' => ['mgp'], + 'application/x-makeself' => ['run'], + 'application/x-mame-chd' => ['chd'], + 'application/x-markaby' => ['mab'], + 'application/x-mathematica' => ['nb'], + 'application/x-mdb' => ['mdb'], + 'application/x-mie' => ['mie'], + 'application/x-mif' => ['mif'], + 'application/x-mimearchive' => ['mhtml', 'mht'], + 'application/x-mobi8-ebook' => ['azw3', 'kfx'], + 'application/x-mobipocket-ebook' => ['prc', 'mobi'], + 'application/x-modrinth-modpack+zip' => ['mrpack'], + 'application/x-ms-application' => ['application'], + 'application/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'], + 'application/x-ms-dos-executable' => ['exe'], + 'application/x-ms-pdb' => ['pdb'], + 'application/x-ms-shortcut' => ['lnk'], + 'application/x-ms-wim' => ['wim', 'swm'], + 'application/x-ms-wmd' => ['wmd'], + 'application/x-ms-wmz' => ['wmz'], + 'application/x-ms-xbap' => ['xbap'], + 'application/x-msaccess' => ['mdb'], + 'application/x-msbinder' => ['obd'], + 'application/x-mscardfile' => ['crd'], + 'application/x-msclip' => ['clp'], + 'application/x-msdos-program' => ['exe'], + 'application/x-msdownload' => ['exe', 'dll', 'com', 'bat', 'msi'], + 'application/x-msexcel' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'], + 'application/x-msi' => ['msi'], + 'application/x-msmediaview' => ['mvb', 'm13', 'm14'], + 'application/x-msmetafile' => ['wmf', 'wmz', 'emf', 'emz'], + 'application/x-msmoney' => ['mny'], + 'application/x-mspowerpoint' => ['ppz', 'ppt', 'pps', 'pot'], + 'application/x-mspublisher' => ['pub'], + 'application/x-msschedule' => ['scd'], + 'application/x-msterminal' => ['trm'], + 'application/x-mswinurl' => ['url'], + 'application/x-msword' => ['doc'], + 'application/x-mswrite' => ['wri'], + 'application/x-msx-rom' => ['msx'], + 'application/x-n64-rom' => ['n64', 'z64', 'v64'], + 'application/x-navi-animation' => ['ani'], + 'application/x-neo-geo-pocket-color-rom' => ['ngc'], + 'application/x-neo-geo-pocket-rom' => ['ngp'], + 'application/x-nes-rom' => ['nes', 'nez', 'unf', 'unif'], + 'application/x-netcdf' => ['nc', 'cdf'], + 'application/x-netshow-channel' => ['nsc'], + 'application/x-nintendo-3ds-executable' => ['3dsx'], + 'application/x-nintendo-3ds-rom' => ['3ds', 'cci'], + 'application/x-nintendo-ds-rom' => ['nds'], + 'application/x-ns-proxy-autoconfig' => ['pac'], + 'application/x-nuscript' => ['nu'], + 'application/x-nzb' => ['nzb'], + 'application/x-object' => ['o', 'mod'], + 'application/x-ogg' => ['ogx'], + 'application/x-oleo' => ['oleo'], + 'application/x-openvpn-profile' => ['openvpn', 'ovpn'], + 'application/x-openzim' => ['zim'], + 'application/x-pagemaker' => ['p65', 'pm', 'pm6', 'pmd'], + 'application/x-pak' => ['pak'], + 'application/x-palm-database' => ['prc', 'pdb', 'pqa', 'oprc'], + 'application/x-par2' => ['PAR2', 'par2'], + 'application/x-partial-download' => ['wkdownload', 'crdownload', 'part'], + 'application/x-pc-engine-rom' => ['pce'], + 'application/x-pcap' => ['pcap', 'cap', 'dmp'], + 'application/x-pdf' => ['pdf'], + 'application/x-perl' => ['pl', 'pm', 'PL', 'al', 'perl', 'pod', 't'], + 'application/x-photoshop' => ['psd'], + 'application/x-php' => ['php', 'php3', 'php4', 'php5', 'phps'], + 'application/x-pilot' => ['prc', 'pdb'], + 'application/x-pkcs12' => ['p12', 'pfx'], + 'application/x-pkcs7-certificates' => ['p7b', 'spc'], + 'application/x-pkcs7-certreqresp' => ['p7r'], + 'application/x-planperfect' => ['pln'], + 'application/x-pocket-word' => ['psw'], + 'application/x-pw' => ['pw'], + 'application/x-pyspread-bz-spreadsheet' => ['pys'], + 'application/x-pyspread-spreadsheet' => ['pysu'], + 'application/x-python-bytecode' => ['pyc', 'pyo'], + 'application/x-qed-disk' => ['qed'], + 'application/x-qemu-disk' => ['qcow2', 'qcow'], + 'application/x-qpress' => ['qp'], + 'application/x-qtiplot' => ['qti', 'qti.gz'], + 'application/x-quattropro' => ['wb1', 'wb2', 'wb3'], + 'application/x-quicktime-media-link' => ['qtl'], + 'application/x-quicktimeplayer' => ['qtl'], + 'application/x-qw' => ['qif'], + 'application/x-rar' => ['rar'], + 'application/x-rar-compressed' => ['rar'], + 'application/x-raw-disk-image' => ['raw-disk-image', 'img'], + 'application/x-raw-disk-image-xz-compressed' => ['raw-disk-image.xz', 'img.xz'], + 'application/x-raw-floppy-disk-image' => ['fd', 'qd'], + 'application/x-redhat-package-manager' => ['rpm'], + 'application/x-reject' => ['rej'], + 'application/x-research-info-systems' => ['ris'], + 'application/x-rnc' => ['rnc'], + 'application/x-rpm' => ['rpm'], + 'application/x-ruby' => ['rb'], + 'application/x-sami' => ['smi', 'sami'], + 'application/x-sap-file' => ['sap'], + 'application/x-saturn-rom' => ['iso'], + 'application/x-sdp' => ['sdp'], + 'application/x-sea' => ['sea'], + 'application/x-sega-cd-rom' => ['iso'], + 'application/x-sega-pico-rom' => ['iso'], + 'application/x-sg1000-rom' => ['sg'], + 'application/x-sh' => ['sh'], + 'application/x-shar' => ['shar'], + 'application/x-shared-library-la' => ['la'], + 'application/x-sharedlib' => ['so'], + 'application/x-shellscript' => ['sh'], + 'application/x-shockwave-flash' => ['swf', 'spl'], + 'application/x-shorten' => ['shn'], + 'application/x-siag' => ['siag'], + 'application/x-silverlight-app' => ['xap'], + 'application/x-sit' => ['sit'], + 'application/x-sitx' => ['sitx'], + 'application/x-smaf' => ['mmf', 'smaf'], + 'application/x-sms-rom' => ['sms'], + 'application/x-snes-rom' => ['sfc', 'smc'], + 'application/x-source-rpm' => ['src.rpm', 'spm'], + 'application/x-spss-por' => ['por'], + 'application/x-spss-sav' => ['sav', 'zsav'], + 'application/x-spss-savefile' => ['sav', 'zsav'], + 'application/x-sql' => ['sql'], + 'application/x-sqlite2' => ['sqlite2'], + 'application/x-sqlite3' => ['sqlite3'], + 'application/x-srt' => ['srt'], + 'application/x-stuffit' => ['sit'], + 'application/x-stuffitx' => ['sitx'], + 'application/x-subrip' => ['srt'], + 'application/x-sv4cpio' => ['sv4cpio'], + 'application/x-sv4crc' => ['sv4crc'], + 'application/x-t3vm-image' => ['t3'], + 'application/x-t602' => ['602'], + 'application/x-tads' => ['gam'], + 'application/x-tar' => ['tar', 'gtar', 'gem'], + 'application/x-targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'application/x-tarz' => ['tar.Z', 'taz'], + 'application/x-tcl' => ['tcl', 'tk'], + 'application/x-tex' => ['tex', 'ltx', 'sty', 'cls', 'dtx', 'ins', 'latex'], + 'application/x-tex-gf' => ['gf'], + 'application/x-tex-pk' => ['pk'], + 'application/x-tex-tfm' => ['tfm'], + 'application/x-texinfo' => ['texinfo', 'texi'], + 'application/x-tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'application/x-tgif' => ['obj'], + 'application/x-theme' => ['theme'], + 'application/x-thomson-cartridge-memo7' => ['m7'], + 'application/x-thomson-cassette' => ['k7'], + 'application/x-thomson-sap-image' => ['sap'], + 'application/x-tiled-tmx' => ['tmx'], + 'application/x-tiled-tsx' => ['tsx'], + 'application/x-trash' => ['bak', 'old', 'sik'], + 'application/x-trig' => ['trig'], + 'application/x-troff' => ['tr', 'roff', 't'], + 'application/x-troff-man' => ['man'], + 'application/x-tzo' => ['tar.lzo', 'tzo'], + 'application/x-ufraw' => ['ufraw'], + 'application/x-ustar' => ['ustar'], + 'application/x-vdi-disk' => ['vdi'], + 'application/x-vhd-disk' => ['vhd', 'vpc'], + 'application/x-vhdx-disk' => ['vhdx'], + 'application/x-virtual-boy-rom' => ['vb'], + 'application/x-virtualbox-hdd' => ['hdd'], + 'application/x-virtualbox-ova' => ['ova'], + 'application/x-virtualbox-ovf' => ['ovf'], + 'application/x-virtualbox-vbox' => ['vbox'], + 'application/x-virtualbox-vbox-extpack' => ['vbox-extpack'], + 'application/x-virtualbox-vdi' => ['vdi'], + 'application/x-virtualbox-vhd' => ['vhd', 'vpc'], + 'application/x-virtualbox-vhdx' => ['vhdx'], + 'application/x-virtualbox-vmdk' => ['vmdk'], + 'application/x-vmdk-disk' => ['vmdk'], + 'application/x-vnd.kde.kexi' => ['kexi'], + 'application/x-wais-source' => ['src'], + 'application/x-wbfs' => ['iso'], + 'application/x-web-app-manifest+json' => ['webapp'], + 'application/x-wia' => ['iso'], + 'application/x-wii-iso-image' => ['iso'], + 'application/x-wii-rom' => ['iso'], + 'application/x-wii-wad' => ['wad'], + 'application/x-windows-themepack' => ['themepack'], + 'application/x-wmf' => ['wmf'], + 'application/x-wonderswan-color-rom' => ['wsc'], + 'application/x-wonderswan-rom' => ['ws'], + 'application/x-wordperfect' => ['wp', 'wp4', 'wp5', 'wp6', 'wpd', 'wpp'], + 'application/x-wpg' => ['wpg'], + 'application/x-wwf' => ['wwf'], + 'application/x-x509-ca-cert' => ['der', 'crt', 'pem', 'cert'], + 'application/x-xar' => ['xar', 'pkg'], + 'application/x-xbel' => ['xbel'], + 'application/x-xfig' => ['fig'], + 'application/x-xliff' => ['xlf', 'xliff'], + 'application/x-xliff+xml' => ['xlf'], + 'application/x-xpinstall' => ['xpi'], + 'application/x-xspf+xml' => ['xspf'], + 'application/x-xz' => ['xz'], + 'application/x-xz-compressed-tar' => ['tar.xz', 'txz'], + 'application/x-xzpdf' => ['pdf.xz'], + 'application/x-yaml' => ['yaml', 'yml'], + 'application/x-zip' => ['zip', 'zipx'], + 'application/x-zip-compressed' => ['zip', 'zipx'], + 'application/x-zip-compressed-fb2' => ['fb2.zip'], + 'application/x-zmachine' => ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'], + 'application/x-zoo' => ['zoo'], + 'application/x-zpaq' => ['zpaq'], + 'application/x-zstd-compressed-tar' => ['tar.zst', 'tzst'], + 'application/xaml+xml' => ['xaml'], + 'application/xcap-att+xml' => ['xav'], + 'application/xcap-caps+xml' => ['xca'], + 'application/xcap-diff+xml' => ['xdf'], + 'application/xcap-el+xml' => ['xel'], + 'application/xcap-error+xml' => ['xer'], + 'application/xcap-ns+xml' => ['xns'], + 'application/xenc+xml' => ['xenc'], + 'application/xhtml+xml' => ['xhtml', 'xht', 'html', 'htm'], + 'application/xliff+xml' => ['xlf', 'xliff'], + 'application/xml' => ['xml', 'xsl', 'xsd', 'rng', 'xbl'], + 'application/xml-dtd' => ['dtd'], + 'application/xml-external-parsed-entity' => ['ent'], + 'application/xop+xml' => ['xop'], + 'application/xproc+xml' => ['xpl'], + 'application/xps' => ['xps'], + 'application/xslt+xml' => ['xsl', 'xslt'], + 'application/xspf+xml' => ['xspf'], + 'application/xv+xml' => ['mxml', 'xhvml', 'xvml', 'xvm'], + 'application/yaml' => ['yaml', 'yml'], + 'application/yang' => ['yang'], + 'application/yin+xml' => ['yin'], + 'application/zip' => ['zip', 'zipx'], + 'application/zlib' => ['zz'], + 'application/zstd' => ['zst'], + 'audio/3gpp' => ['3gpp', '3gp', '3ga'], + 'audio/3gpp-encrypted' => ['3gp', '3gpp', '3ga'], + 'audio/3gpp2' => ['3g2', '3gp2', '3gpp2'], + 'audio/aac' => ['aac', 'adts', 'ass'], + 'audio/ac3' => ['ac3'], + 'audio/adpcm' => ['adp'], + 'audio/amr' => ['amr'], + 'audio/amr-encrypted' => ['amr'], + 'audio/amr-wb' => ['awb'], + 'audio/amr-wb-encrypted' => ['awb'], + 'audio/annodex' => ['axa'], + 'audio/basic' => ['au', 'snd'], + 'audio/dff' => ['dff'], + 'audio/dsd' => ['dsf'], + 'audio/dsf' => ['dsf'], + 'audio/flac' => ['flac'], + 'audio/imelody' => ['imy', 'ime'], + 'audio/m3u' => ['m3u', 'm3u8', 'vlc'], + 'audio/m4a' => ['m4a', 'f4a'], + 'audio/midi' => ['mid', 'midi', 'kar', 'rmi'], + 'audio/mobile-xmf' => ['mxmf'], + 'audio/mp2' => ['mp2'], + 'audio/mp3' => ['mp3', 'mpga'], + 'audio/mp4' => ['m4a', 'mp4a', 'f4a'], + 'audio/mpeg' => ['mp3', 'mpga', 'mp2', 'mp2a', 'm2a', 'm3a'], + 'audio/mpegurl' => ['m3u', 'm3u8', 'vlc'], + 'audio/ogg' => ['ogg', 'oga', 'spx', 'opus'], + 'audio/prs.sid' => ['sid', 'psid'], + 'audio/s3m' => ['s3m'], + 'audio/scpls' => ['pls'], + 'audio/silk' => ['sil'], + 'audio/tta' => ['tta'], + 'audio/usac' => ['loas', 'xhe'], + 'audio/vnd.audible' => ['aa', 'aax'], + 'audio/vnd.audible.aax' => ['aax'], + 'audio/vnd.audible.aaxc' => ['aaxc'], + 'audio/vnd.dece.audio' => ['uva', 'uvva'], + 'audio/vnd.digital-winds' => ['eol'], + 'audio/vnd.dra' => ['dra'], + 'audio/vnd.dts' => ['dts'], + 'audio/vnd.dts.hd' => ['dtshd'], + 'audio/vnd.lucent.voice' => ['lvp'], + 'audio/vnd.m-realaudio' => ['ra', 'rax'], + 'audio/vnd.ms-playready.media.pya' => ['pya'], + 'audio/vnd.nokia.mobile-xmf' => ['mxmf'], + 'audio/vnd.nuera.ecelp4800' => ['ecelp4800'], + 'audio/vnd.nuera.ecelp7470' => ['ecelp7470'], + 'audio/vnd.nuera.ecelp9600' => ['ecelp9600'], + 'audio/vnd.rip' => ['rip'], + 'audio/vnd.rn-realaudio' => ['ra', 'rax'], + 'audio/vnd.wave' => ['wav'], + 'audio/vorbis' => ['oga', 'ogg'], + 'audio/wav' => ['wav'], + 'audio/wave' => ['wav'], + 'audio/webm' => ['weba'], + 'audio/wma' => ['wma'], + 'audio/x-aac' => ['aac', 'adts', 'ass'], + 'audio/x-aifc' => ['aifc', 'aiffc'], + 'audio/x-aiff' => ['aif', 'aiff', 'aifc'], + 'audio/x-aiffc' => ['aifc', 'aiffc'], + 'audio/x-amzxml' => ['amz'], + 'audio/x-annodex' => ['axa'], + 'audio/x-ape' => ['ape'], + 'audio/x-caf' => ['caf'], + 'audio/x-dff' => ['dff'], + 'audio/x-dsd' => ['dsf'], + 'audio/x-dsf' => ['dsf'], + 'audio/x-dts' => ['dts'], + 'audio/x-dtshd' => ['dtshd'], + 'audio/x-flac' => ['flac'], + 'audio/x-flac+ogg' => ['oga', 'ogg'], + 'audio/x-gsm' => ['gsm'], + 'audio/x-hx-aac-adts' => ['aac', 'adts', 'ass'], + 'audio/x-imelody' => ['imy', 'ime'], + 'audio/x-iriver-pla' => ['pla'], + 'audio/x-it' => ['it'], + 'audio/x-m3u' => ['m3u', 'm3u8', 'vlc'], + 'audio/x-m4a' => ['m4a', 'f4a'], + 'audio/x-m4b' => ['m4b', 'f4b'], + 'audio/x-m4r' => ['m4r'], + 'audio/x-matroska' => ['mka'], + 'audio/x-midi' => ['mid', 'midi', 'kar'], + 'audio/x-minipsf' => ['minipsf'], + 'audio/x-mo3' => ['mo3'], + 'audio/x-mod' => ['mod', 'ult', 'uni', 'm15', 'mtm', '669', 'med'], + 'audio/x-mp2' => ['mp2'], + 'audio/x-mp3' => ['mp3', 'mpga'], + 'audio/x-mp3-playlist' => ['m3u', 'm3u8', 'vlc'], + 'audio/x-mpeg' => ['mp3', 'mpga'], + 'audio/x-mpegurl' => ['m3u', 'm3u8', 'vlc'], + 'audio/x-mpg' => ['mp3', 'mpga'], + 'audio/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'], + 'audio/x-ms-wax' => ['wax'], + 'audio/x-ms-wma' => ['wma'], + 'audio/x-ms-wmv' => ['wmv'], + 'audio/x-musepack' => ['mpc', 'mpp', 'mp+'], + 'audio/x-ogg' => ['oga', 'ogg', 'opus'], + 'audio/x-oggflac' => ['oga', 'ogg'], + 'audio/x-opus+ogg' => ['opus'], + 'audio/x-pn-audibleaudio' => ['aa', 'aax'], + 'audio/x-pn-realaudio' => ['ram', 'ra', 'rax'], + 'audio/x-pn-realaudio-plugin' => ['rmp'], + 'audio/x-psf' => ['psf'], + 'audio/x-psflib' => ['psflib'], + 'audio/x-realaudio' => ['ra'], + 'audio/x-rn-3gpp-amr' => ['3gp', '3gpp', '3ga'], + 'audio/x-rn-3gpp-amr-encrypted' => ['3gp', '3gpp', '3ga'], + 'audio/x-rn-3gpp-amr-wb' => ['3gp', '3gpp', '3ga'], + 'audio/x-rn-3gpp-amr-wb-encrypted' => ['3gp', '3gpp', '3ga'], + 'audio/x-s3m' => ['s3m'], + 'audio/x-scpls' => ['pls'], + 'audio/x-shorten' => ['shn'], + 'audio/x-speex' => ['spx'], + 'audio/x-speex+ogg' => ['oga', 'ogg', 'spx'], + 'audio/x-stm' => ['stm'], + 'audio/x-tak' => ['tak'], + 'audio/x-tta' => ['tta'], + 'audio/x-voc' => ['voc'], + 'audio/x-vorbis' => ['oga', 'ogg'], + 'audio/x-vorbis+ogg' => ['oga', 'ogg'], + 'audio/x-wav' => ['wav'], + 'audio/x-wavpack' => ['wv', 'wvp'], + 'audio/x-wavpack-correction' => ['wvc'], + 'audio/x-xi' => ['xi'], + 'audio/x-xm' => ['xm'], + 'audio/x-xmf' => ['xmf'], + 'audio/xm' => ['xm'], + 'audio/xmf' => ['xmf'], + 'chemical/x-cdx' => ['cdx'], + 'chemical/x-cif' => ['cif'], + 'chemical/x-cmdf' => ['cmdf'], + 'chemical/x-cml' => ['cml'], + 'chemical/x-csml' => ['csml'], + 'chemical/x-xyz' => ['xyz'], + 'flv-application/octet-stream' => ['flv'], + 'font/collection' => ['ttc'], + 'font/otf' => ['otf'], + 'font/ttf' => ['ttf'], + 'font/woff' => ['woff'], + 'font/woff2' => ['woff2'], + 'image/aces' => ['exr'], + 'image/apng' => ['apng', 'png'], + 'image/astc' => ['astc'], + 'image/avci' => ['avci'], + 'image/avcs' => ['avcs'], + 'image/avif' => ['avif', 'avifs'], + 'image/avif-sequence' => ['avif', 'avifs'], + 'image/bmp' => ['bmp', 'dib'], + 'image/cdr' => ['cdr'], + 'image/cgm' => ['cgm'], + 'image/dicom-rle' => ['drle'], + 'image/emf' => ['emf'], + 'image/fax-g3' => ['g3'], + 'image/fits' => ['fits', 'fit', 'fts'], + 'image/g3fax' => ['g3'], + 'image/gif' => ['gif'], + 'image/heic' => ['heic', 'heif', 'hif'], + 'image/heic-sequence' => ['heics', 'heic', 'heif', 'hif'], + 'image/heif' => ['heif', 'heic', 'hif'], + 'image/heif-sequence' => ['heifs', 'heic', 'heif', 'hif'], + 'image/hej2k' => ['hej2'], + 'image/hsj2' => ['hsj2'], + 'image/ico' => ['ico'], + 'image/icon' => ['ico'], + 'image/ief' => ['ief'], + 'image/jls' => ['jls'], + 'image/jp2' => ['jp2', 'jpg2'], + 'image/jpeg' => ['jpg', 'jpeg', 'jpe'], + 'image/jpeg2000' => ['jp2', 'jpg2'], + 'image/jpeg2000-image' => ['jp2', 'jpg2'], + 'image/jph' => ['jph'], + 'image/jphc' => ['jhc'], + 'image/jpm' => ['jpm', 'jpgm'], + 'image/jpx' => ['jpx', 'jpf'], + 'image/jxl' => ['jxl'], + 'image/jxr' => ['jxr', 'hdp', 'wdp'], + 'image/jxra' => ['jxra'], + 'image/jxrs' => ['jxrs'], + 'image/jxs' => ['jxs'], + 'image/jxsc' => ['jxsc'], + 'image/jxsi' => ['jxsi'], + 'image/jxss' => ['jxss'], + 'image/ktx' => ['ktx'], + 'image/ktx2' => ['ktx2'], + 'image/openraster' => ['ora'], + 'image/pdf' => ['pdf'], + 'image/photoshop' => ['psd'], + 'image/pjpeg' => ['jpg', 'jpeg', 'jpe'], + 'image/png' => ['png'], + 'image/prs.btif' => ['btif'], + 'image/prs.pti' => ['pti'], + 'image/psd' => ['psd'], + 'image/qoi' => ['qoi'], + 'image/rle' => ['rle'], + 'image/sgi' => ['sgi'], + 'image/svg' => ['svg'], + 'image/svg+xml' => ['svg', 'svgz'], + 'image/svg+xml-compressed' => ['svgz', 'svg.gz'], + 'image/t38' => ['t38'], + 'image/targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/tiff' => ['tif', 'tiff'], + 'image/tiff-fx' => ['tfx'], + 'image/vnd.adobe.photoshop' => ['psd'], + 'image/vnd.airzip.accelerator.azv' => ['azv'], + 'image/vnd.dece.graphic' => ['uvi', 'uvvi', 'uvg', 'uvvg'], + 'image/vnd.djvu' => ['djvu', 'djv'], + 'image/vnd.djvu+multipage' => ['djvu', 'djv'], + 'image/vnd.dvb.subtitle' => ['sub'], + 'image/vnd.dwg' => ['dwg'], + 'image/vnd.dxf' => ['dxf'], + 'image/vnd.fastbidsheet' => ['fbs'], + 'image/vnd.fpx' => ['fpx'], + 'image/vnd.fst' => ['fst'], + 'image/vnd.fujixerox.edmics-mmr' => ['mmr'], + 'image/vnd.fujixerox.edmics-rlc' => ['rlc'], + 'image/vnd.microsoft.icon' => ['ico'], + 'image/vnd.mozilla.apng' => ['apng', 'png'], + 'image/vnd.ms-dds' => ['dds'], + 'image/vnd.ms-modi' => ['mdi'], + 'image/vnd.ms-photo' => ['wdp', 'jxr', 'hdp'], + 'image/vnd.net-fpx' => ['npx'], + 'image/vnd.pco.b16' => ['b16'], + 'image/vnd.rn-realpix' => ['rp'], + 'image/vnd.tencent.tap' => ['tap'], + 'image/vnd.valve.source.texture' => ['vtf'], + 'image/vnd.wap.wbmp' => ['wbmp'], + 'image/vnd.xiff' => ['xif'], + 'image/vnd.zbrush.pcx' => ['pcx'], + 'image/webp' => ['webp'], + 'image/wmf' => ['wmf'], + 'image/x-3ds' => ['3ds'], + 'image/x-adobe-dng' => ['dng'], + 'image/x-applix-graphics' => ['ag'], + 'image/x-bmp' => ['bmp', 'dib'], + 'image/x-bzeps' => ['eps.bz2', 'epsi.bz2', 'epsf.bz2'], + 'image/x-canon-cr2' => ['cr2'], + 'image/x-canon-cr3' => ['cr3'], + 'image/x-canon-crw' => ['crw'], + 'image/x-cdr' => ['cdr'], + 'image/x-cmu-raster' => ['ras'], + 'image/x-cmx' => ['cmx'], + 'image/x-compressed-xcf' => ['xcf.gz', 'xcf.bz2'], + 'image/x-dds' => ['dds'], + 'image/x-djvu' => ['djvu', 'djv'], + 'image/x-emf' => ['emf'], + 'image/x-eps' => ['eps', 'epsi', 'epsf'], + 'image/x-exr' => ['exr'], + 'image/x-fits' => ['fits', 'fit', 'fts'], + 'image/x-freehand' => ['fh', 'fhc', 'fh4', 'fh5', 'fh7'], + 'image/x-fuji-raf' => ['raf'], + 'image/x-gimp-gbr' => ['gbr'], + 'image/x-gimp-gih' => ['gih'], + 'image/x-gimp-pat' => ['pat'], + 'image/x-gzeps' => ['eps.gz', 'epsi.gz', 'epsf.gz'], + 'image/x-icb' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/x-icns' => ['icns'], + 'image/x-ico' => ['ico'], + 'image/x-icon' => ['ico'], + 'image/x-iff' => ['iff', 'ilbm', 'lbm'], + 'image/x-ilbm' => ['iff', 'ilbm', 'lbm'], + 'image/x-jng' => ['jng'], + 'image/x-jp2-codestream' => ['j2c', 'j2k', 'jpc'], + 'image/x-jpeg2000-image' => ['jp2', 'jpg2'], + 'image/x-kodak-dcr' => ['dcr'], + 'image/x-kodak-k25' => ['k25'], + 'image/x-kodak-kdc' => ['kdc'], + 'image/x-lwo' => ['lwo', 'lwob'], + 'image/x-lws' => ['lws'], + 'image/x-macpaint' => ['pntg'], + 'image/x-minolta-mrw' => ['mrw'], + 'image/x-mrsid-image' => ['sid'], + 'image/x-ms-bmp' => ['bmp', 'dib'], + 'image/x-msod' => ['msod'], + 'image/x-nikon-nef' => ['nef'], + 'image/x-nikon-nrw' => ['nrw'], + 'image/x-olympus-orf' => ['orf'], + 'image/x-panasonic-raw' => ['raw'], + 'image/x-panasonic-raw2' => ['rw2'], + 'image/x-panasonic-rw' => ['raw'], + 'image/x-panasonic-rw2' => ['rw2'], + 'image/x-pcx' => ['pcx'], + 'image/x-pentax-pef' => ['pef'], + 'image/x-photo-cd' => ['pcd'], + 'image/x-photoshop' => ['psd'], + 'image/x-pict' => ['pic', 'pct', 'pict', 'pict1', 'pict2'], + 'image/x-portable-anymap' => ['pnm'], + 'image/x-portable-bitmap' => ['pbm'], + 'image/x-portable-graymap' => ['pgm'], + 'image/x-portable-pixmap' => ['ppm'], + 'image/x-psd' => ['psd'], + 'image/x-quicktime' => ['qtif', 'qif'], + 'image/x-rgb' => ['rgb'], + 'image/x-sgi' => ['sgi'], + 'image/x-sigma-x3f' => ['x3f'], + 'image/x-skencil' => ['sk', 'sk1'], + 'image/x-sony-arw' => ['arw'], + 'image/x-sony-sr2' => ['sr2'], + 'image/x-sony-srf' => ['srf'], + 'image/x-sun-raster' => ['sun'], + 'image/x-targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/x-tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'], + 'image/x-win-bitmap' => ['cur'], + 'image/x-win-metafile' => ['wmf'], + 'image/x-wmf' => ['wmf'], + 'image/x-xbitmap' => ['xbm'], + 'image/x-xcf' => ['xcf'], + 'image/x-xfig' => ['fig'], + 'image/x-xpixmap' => ['xpm'], + 'image/x-xpm' => ['xpm'], + 'image/x-xwindowdump' => ['xwd'], + 'image/x.djvu' => ['djvu', 'djv'], + 'message/disposition-notification' => ['disposition-notification'], + 'message/global' => ['u8msg'], + 'message/global-delivery-status' => ['u8dsn'], + 'message/global-disposition-notification' => ['u8mdn'], + 'message/global-headers' => ['u8hdr'], + 'message/rfc822' => ['eml', 'mime'], + 'message/vnd.wfa.wsc' => ['wsc'], + 'model/3mf' => ['3mf'], + 'model/gltf+json' => ['gltf'], + 'model/gltf-binary' => ['glb'], + 'model/iges' => ['igs', 'iges'], + 'model/mesh' => ['msh', 'mesh', 'silo'], + 'model/mtl' => ['mtl'], + 'model/obj' => ['obj'], + 'model/step+xml' => ['stpx'], + 'model/step+zip' => ['stpz'], + 'model/step-xml+zip' => ['stpxz'], + 'model/stl' => ['stl'], + 'model/vnd.collada+xml' => ['dae'], + 'model/vnd.dwf' => ['dwf'], + 'model/vnd.gdl' => ['gdl'], + 'model/vnd.gtw' => ['gtw'], + 'model/vnd.mts' => ['mts'], + 'model/vnd.opengex' => ['ogex'], + 'model/vnd.parasolid.transmit.binary' => ['x_b'], + 'model/vnd.parasolid.transmit.text' => ['x_t'], + 'model/vnd.sap.vds' => ['vds'], + 'model/vnd.usdz+zip' => ['usdz'], + 'model/vnd.valve.source.compiled-map' => ['bsp'], + 'model/vnd.vtu' => ['vtu'], + 'model/vrml' => ['wrl', 'vrml', 'vrm'], + 'model/x.stl-ascii' => ['stl'], + 'model/x.stl-binary' => ['stl'], + 'model/x3d+binary' => ['x3db', 'x3dbz'], + 'model/x3d+fastinfoset' => ['x3db'], + 'model/x3d+vrml' => ['x3dv', 'x3dvz'], + 'model/x3d+xml' => ['x3d', 'x3dz'], + 'model/x3d-vrml' => ['x3dv'], + 'text/cache-manifest' => ['appcache', 'manifest'], + 'text/calendar' => ['ics', 'ifb', 'vcs'], + 'text/coffeescript' => ['coffee', 'litcoffee'], + 'text/crystal' => ['cr'], + 'text/css' => ['css'], + 'text/csv' => ['csv'], + 'text/csv-schema' => ['csvs'], + 'text/directory' => ['vcard', 'vcf', 'vct', 'gcrd'], + 'text/ecmascript' => ['es'], + 'text/gedcom' => ['ged', 'gedcom'], + 'text/google-video-pointer' => ['gvp'], + 'text/html' => ['html', 'htm', 'shtml'], + 'text/ico' => ['ico'], + 'text/jade' => ['jade'], + 'text/javascript' => ['js', 'jsm', 'mjs'], + 'text/jsx' => ['jsx'], + 'text/julia' => ['jl'], + 'text/less' => ['less'], + 'text/markdown' => ['md', 'markdown', 'mkd'], + 'text/mathml' => ['mml'], + 'text/mdx' => ['mdx'], + 'text/n3' => ['n3'], + 'text/org' => ['org'], + 'text/plain' => ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini', 'asc'], + 'text/prs.lines.tag' => ['dsc'], + 'text/rdf' => ['rdf', 'rdfs', 'owl'], + 'text/richtext' => ['rtx'], + 'text/rss' => ['rss'], + 'text/rtf' => ['rtf'], + 'text/rust' => ['rs'], + 'text/sgml' => ['sgml', 'sgm'], + 'text/shex' => ['shex'], + 'text/slim' => ['slim', 'slm'], + 'text/spdx' => ['spdx'], + 'text/spreadsheet' => ['sylk', 'slk'], + 'text/stylus' => ['stylus', 'styl'], + 'text/tab-separated-values' => ['tsv'], + 'text/tcl' => ['tcl', 'tk'], + 'text/troff' => ['t', 'tr', 'roff', 'man', 'me', 'ms'], + 'text/turtle' => ['ttl'], + 'text/uri-list' => ['uri', 'uris', 'urls'], + 'text/vbs' => ['vbs'], + 'text/vbscript' => ['vbs'], + 'text/vcard' => ['vcard', 'vcf', 'vct', 'gcrd'], + 'text/vnd.curl' => ['curl'], + 'text/vnd.curl.dcurl' => ['dcurl'], + 'text/vnd.curl.mcurl' => ['mcurl'], + 'text/vnd.curl.scurl' => ['scurl'], + 'text/vnd.dvb.subtitle' => ['sub'], + 'text/vnd.familysearch.gedcom' => ['ged', 'gedcom'], + 'text/vnd.fly' => ['fly'], + 'text/vnd.fmi.flexstor' => ['flx'], + 'text/vnd.graphviz' => ['gv', 'dot'], + 'text/vnd.in3d.3dml' => ['3dml'], + 'text/vnd.in3d.spot' => ['spot'], + 'text/vnd.qt.linguist' => ['ts'], + 'text/vnd.rn-realtext' => ['rt'], + 'text/vnd.senx.warpscript' => ['mc2'], + 'text/vnd.sun.j2me.app-descriptor' => ['jad'], + 'text/vnd.trolltech.linguist' => ['ts'], + 'text/vnd.wap.wml' => ['wml'], + 'text/vnd.wap.wmlscript' => ['wmls'], + 'text/vtt' => ['vtt'], + 'text/x-adasrc' => ['adb', 'ads'], + 'text/x-asm' => ['s', 'asm'], + 'text/x-bibtex' => ['bib'], + 'text/x-blueprint' => ['blp'], + 'text/x-c' => ['c', 'cc', 'cxx', 'cpp', 'h', 'hh', 'dic'], + 'text/x-c++hdr' => ['hh', 'hp', 'hpp', 'h++', 'hxx'], + 'text/x-c++src' => ['cpp', 'cxx', 'cc', 'C', 'c++'], + 'text/x-chdr' => ['h'], + 'text/x-cmake' => ['cmake'], + 'text/x-cobol' => ['cbl', 'cob'], + 'text/x-comma-separated-values' => ['csv'], + 'text/x-common-lisp' => ['asd', 'fasl', 'lisp', 'ros'], + 'text/x-component' => ['htc'], + 'text/x-crystal' => ['cr'], + 'text/x-csharp' => ['cs'], + 'text/x-csrc' => ['c'], + 'text/x-csv' => ['csv'], + 'text/x-dart' => ['dart'], + 'text/x-dbus-service' => ['service'], + 'text/x-dcl' => ['dcl'], + 'text/x-devicetree-binary' => ['dtb'], + 'text/x-devicetree-source' => ['dts', 'dtsi'], + 'text/x-diff' => ['diff', 'patch'], + 'text/x-dsl' => ['dsl'], + 'text/x-dsrc' => ['d', 'di'], + 'text/x-dtd' => ['dtd'], + 'text/x-eiffel' => ['e', 'eif'], + 'text/x-elixir' => ['ex', 'exs'], + 'text/x-emacs-lisp' => ['el'], + 'text/x-erlang' => ['erl'], + 'text/x-fish' => ['fish'], + 'text/x-fortran' => ['f', 'for', 'f77', 'f90', 'f95'], + 'text/x-gcode-gx' => ['gx'], + 'text/x-genie' => ['gs'], + 'text/x-gettext-translation' => ['po'], + 'text/x-gettext-translation-template' => ['pot'], + 'text/x-gherkin' => ['feature'], + 'text/x-go' => ['go'], + 'text/x-google-video-pointer' => ['gvp'], + 'text/x-gradle' => ['gradle'], + 'text/x-groovy' => ['groovy', 'gvy', 'gy', 'gsh'], + 'text/x-handlebars-template' => ['hbs'], + 'text/x-haskell' => ['hs'], + 'text/x-idl' => ['idl'], + 'text/x-imelody' => ['imy', 'ime'], + 'text/x-iptables' => ['iptables'], + 'text/x-java' => ['java'], + 'text/x-java-source' => ['java'], + 'text/x-kaitai-struct' => ['ksy'], + 'text/x-kotlin' => ['kt'], + 'text/x-ldif' => ['ldif'], + 'text/x-lilypond' => ['ly'], + 'text/x-literate-haskell' => ['lhs'], + 'text/x-log' => ['log'], + 'text/x-lua' => ['lua'], + 'text/x-lyx' => ['lyx'], + 'text/x-makefile' => ['mk', 'mak'], + 'text/x-markdown' => ['md', 'mkd', 'markdown'], + 'text/x-matlab' => ['m'], + 'text/x-microdvd' => ['sub'], + 'text/x-moc' => ['moc'], + 'text/x-modelica' => ['mo'], + 'text/x-mof' => ['mof'], + 'text/x-mpl2' => ['mpl'], + 'text/x-mpsub' => ['sub'], + 'text/x-mrml' => ['mrml', 'mrl'], + 'text/x-ms-regedit' => ['reg'], + 'text/x-mup' => ['mup', 'not'], + 'text/x-nfo' => ['nfo'], + 'text/x-nim' => ['nim'], + 'text/x-nimscript' => ['nims', 'nimble'], + 'text/x-nu' => ['nu'], + 'text/x-objc++src' => ['mm'], + 'text/x-objcsrc' => ['m'], + 'text/x-ocaml' => ['ml', 'mli'], + 'text/x-ocl' => ['ocl'], + 'text/x-octave' => ['m'], + 'text/x-ooc' => ['ooc'], + 'text/x-opencl-src' => ['cl'], + 'text/x-opml' => ['opml'], + 'text/x-opml+xml' => ['opml'], + 'text/x-org' => ['org'], + 'text/x-pascal' => ['p', 'pas'], + 'text/x-patch' => ['diff', 'patch'], + 'text/x-perl' => ['pl', 'PL', 'pm', 'al', 'perl', 'pod', 't'], + 'text/x-po' => ['po'], + 'text/x-pot' => ['pot'], + 'text/x-processing' => ['pde'], + 'text/x-python' => ['py', 'pyx', 'wsgi'], + 'text/x-python3' => ['py', 'py3', 'py3x', 'pyi'], + 'text/x-qml' => ['qml', 'qmltypes', 'qmlproject'], + 'text/x-reject' => ['rej'], + 'text/x-rpm-spec' => ['spec'], + 'text/x-rst' => ['rst'], + 'text/x-sagemath' => ['sage'], + 'text/x-sass' => ['sass'], + 'text/x-scala' => ['scala', 'sc'], + 'text/x-scheme' => ['scm', 'ss'], + 'text/x-scss' => ['scss'], + 'text/x-setext' => ['etx'], + 'text/x-sfv' => ['sfv'], + 'text/x-sh' => ['sh'], + 'text/x-sql' => ['sql'], + 'text/x-ssa' => ['ssa', 'ass'], + 'text/x-subviewer' => ['sub'], + 'text/x-suse-ymp' => ['ymp'], + 'text/x-svhdr' => ['svh'], + 'text/x-svsrc' => ['sv'], + 'text/x-systemd-unit' => ['automount', 'device', 'mount', 'path', 'scope', 'service', 'slice', 'socket', 'swap', 'target', 'timer'], + 'text/x-tcl' => ['tcl', 'tk'], + 'text/x-tex' => ['tex', 'ltx', 'sty', 'cls', 'dtx', 'ins', 'latex'], + 'text/x-texinfo' => ['texi', 'texinfo'], + 'text/x-troff' => ['tr', 'roff', 't'], + 'text/x-troff-me' => ['me'], + 'text/x-troff-mm' => ['mm'], + 'text/x-troff-ms' => ['ms'], + 'text/x-twig' => ['twig'], + 'text/x-txt2tags' => ['t2t'], + 'text/x-typst' => ['typ'], + 'text/x-uil' => ['uil'], + 'text/x-uuencode' => ['uu', 'uue'], + 'text/x-vala' => ['vala', 'vapi'], + 'text/x-vcalendar' => ['vcs', 'ics'], + 'text/x-vcard' => ['vcf', 'vcard', 'vct', 'gcrd'], + 'text/x-verilog' => ['v'], + 'text/x-vhdl' => ['vhd', 'vhdl'], + 'text/x-xmi' => ['xmi'], + 'text/x-xslfo' => ['fo', 'xslfo'], + 'text/x-yaml' => ['yaml', 'yml'], + 'text/x.gcode' => ['gcode'], + 'text/xml' => ['xml', 'xbl', 'xsd', 'rng'], + 'text/xml-external-parsed-entity' => ['ent'], + 'text/yaml' => ['yaml', 'yml'], + 'video/3gp' => ['3gp', '3gpp', '3ga'], + 'video/3gpp' => ['3gp', '3gpp', '3ga'], + 'video/3gpp-encrypted' => ['3gp', '3gpp', '3ga'], + 'video/3gpp2' => ['3g2', '3gp2', '3gpp2'], + 'video/annodex' => ['axv'], + 'video/avi' => ['avi', 'avf', 'divx'], + 'video/divx' => ['avi', 'avf', 'divx'], + 'video/dv' => ['dv'], + 'video/fli' => ['fli', 'flc'], + 'video/flv' => ['flv'], + 'video/h261' => ['h261'], + 'video/h263' => ['h263'], + 'video/h264' => ['h264'], + 'video/iso.segment' => ['m4s'], + 'video/jpeg' => ['jpgv'], + 'video/jpm' => ['jpm', 'jpgm'], + 'video/mj2' => ['mj2', 'mjp2'], + 'video/mp2t' => ['ts', 'm2t', 'm2ts', 'mts', 'cpi', 'clpi', 'mpl', 'mpls', 'bdm', 'bdmv'], + 'video/mp4' => ['mp4', 'mp4v', 'mpg4', 'm4v', 'f4v', 'lrv'], + 'video/mp4v-es' => ['mp4', 'm4v', 'f4v', 'lrv'], + 'video/mpeg' => ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v', 'mp2', 'vob'], + 'video/mpeg-system' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'], + 'video/msvideo' => ['avi', 'avf', 'divx'], + 'video/ogg' => ['ogv', 'ogg'], + 'video/quicktime' => ['mov', 'qt', 'moov', 'qtvr'], + 'video/vivo' => ['viv', 'vivo'], + 'video/vnd.avi' => ['avi', 'avf', 'divx'], + 'video/vnd.dece.hd' => ['uvh', 'uvvh'], + 'video/vnd.dece.mobile' => ['uvm', 'uvvm'], + 'video/vnd.dece.pd' => ['uvp', 'uvvp'], + 'video/vnd.dece.sd' => ['uvs', 'uvvs'], + 'video/vnd.dece.video' => ['uvv', 'uvvv'], + 'video/vnd.divx' => ['avi', 'avf', 'divx'], + 'video/vnd.dvb.file' => ['dvb'], + 'video/vnd.fvt' => ['fvt'], + 'video/vnd.mpegurl' => ['mxu', 'm4u', 'm1u'], + 'video/vnd.ms-playready.media.pyv' => ['pyv'], + 'video/vnd.radgamettools.bink' => ['bik', 'bk2'], + 'video/vnd.radgamettools.smacker' => ['smk'], + 'video/vnd.rn-realvideo' => ['rv', 'rvx'], + 'video/vnd.uvvu.mp4' => ['uvu', 'uvvu'], + 'video/vnd.vivo' => ['viv', 'vivo'], + 'video/vnd.youtube.yt' => ['yt'], + 'video/webm' => ['webm'], + 'video/x-anim' => ['anim1', 'anim2', 'anim3', 'anim4', 'anim5', 'anim6', 'anim7', 'anim8', 'anim9', 'animj'], + 'video/x-annodex' => ['axv'], + 'video/x-avi' => ['avi', 'avf', 'divx'], + 'video/x-f4v' => ['f4v'], + 'video/x-fli' => ['fli', 'flc'], + 'video/x-flic' => ['fli', 'flc'], + 'video/x-flv' => ['flv'], + 'video/x-javafx' => ['fxm'], + 'video/x-m4v' => ['m4v', 'mp4', 'f4v', 'lrv'], + 'video/x-matroska' => ['mkv', 'mk3d', 'mks'], + 'video/x-matroska-3d' => ['mk3d'], + 'video/x-mjpeg' => ['mjpeg', 'mjpg'], + 'video/x-mng' => ['mng'], + 'video/x-mpeg' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'], + 'video/x-mpeg-system' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'], + 'video/x-mpeg2' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'], + 'video/x-mpegurl' => ['m1u', 'm4u', 'mxu'], + 'video/x-ms-asf' => ['asf', 'asx'], + 'video/x-ms-asf-plugin' => ['asf'], + 'video/x-ms-vob' => ['vob'], + 'video/x-ms-wax' => ['asx', 'wax', 'wvx', 'wmx'], + 'video/x-ms-wm' => ['wm', 'asf'], + 'video/x-ms-wmv' => ['wmv'], + 'video/x-ms-wmx' => ['wmx', 'asx', 'wax', 'wvx'], + 'video/x-ms-wvx' => ['wvx', 'asx', 'wax', 'wmx'], + 'video/x-msvideo' => ['avi', 'avf', 'divx'], + 'video/x-nsv' => ['nsv'], + 'video/x-ogg' => ['ogv', 'ogg'], + 'video/x-ogm' => ['ogm'], + 'video/x-ogm+ogg' => ['ogm'], + 'video/x-real-video' => ['rv', 'rvx'], + 'video/x-sgi-movie' => ['movie'], + 'video/x-smv' => ['smv'], + 'video/x-theora' => ['ogg'], + 'video/x-theora+ogg' => ['ogg'], + 'x-conference/x-cooltalk' => ['ice'], + 'x-epoc/x-sisx-app' => ['sisx'], + 'zz-application/zz-winassoc-123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'], + 'zz-application/zz-winassoc-cab' => ['cab'], + 'zz-application/zz-winassoc-cdr' => ['cdr'], + 'zz-application/zz-winassoc-doc' => ['doc'], + 'zz-application/zz-winassoc-hlp' => ['hlp'], + 'zz-application/zz-winassoc-mdb' => ['mdb'], + 'zz-application/zz-winassoc-uu' => ['uue'], + 'zz-application/zz-winassoc-xls' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'], + ]; + + private const REVERSE_MAP = [ + '123' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + '1km' => ['application/vnd.1000minds.decision-model+xml'], + '32x' => ['application/x-genesis-32x-rom'], + '3dml' => ['text/vnd.in3d.3dml'], + '3ds' => ['application/x-nintendo-3ds-rom', 'image/x-3ds'], + '3dsx' => ['application/x-nintendo-3ds-executable'], + '3g2' => ['audio/3gpp2', 'video/3gpp2'], + '3ga' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'], + '3gp' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'], + '3gp2' => ['audio/3gpp2', 'video/3gpp2'], + '3gpp' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'], + '3gpp2' => ['audio/3gpp2', 'video/3gpp2'], + '3mf' => ['application/vnd.ms-3mfdocument', 'model/3mf'], + '602' => ['application/x-t602'], + '669' => ['audio/x-mod'], + '7z' => ['application/x-7z-compressed'], + '7z.001' => ['application/x-7z-compressed'], + 'BLEND' => ['application/x-blender'], + 'C' => ['text/x-c++src'], + 'PAR2' => ['application/x-par2'], + 'PL' => ['application/x-perl', 'text/x-perl'], + 'Z' => ['application/x-compress'], + 'a' => ['application/x-archive'], + 'a26' => ['application/x-atari-2600-rom'], + 'a78' => ['application/x-atari-7800-rom'], + 'aa' => ['audio/vnd.audible', 'audio/x-pn-audibleaudio'], + 'aab' => ['application/x-authorware-bin'], + 'aac' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'], + 'aam' => ['application/x-authorware-map'], + 'aas' => ['application/x-authorware-seg'], + 'aax' => ['audio/vnd.audible', 'audio/vnd.audible.aax', 'audio/x-pn-audibleaudio'], + 'aaxc' => ['audio/vnd.audible.aaxc'], + 'abw' => ['application/x-abiword'], + 'abw.CRASHED' => ['application/x-abiword'], + 'abw.gz' => ['application/x-abiword'], + 'ac' => ['application/pkix-attr-cert', 'application/vnd.nokia.n-gage.ac+xml'], + 'ac3' => ['audio/ac3'], + 'acc' => ['application/vnd.americandynamics.acc'], + 'ace' => ['application/x-ace', 'application/x-ace-compressed'], + 'acu' => ['application/vnd.acucobol'], + 'acutc' => ['application/vnd.acucorp'], + 'adb' => ['text/x-adasrc'], + 'adf' => ['application/x-amiga-disk-format'], + 'adp' => ['audio/adpcm'], + 'ads' => ['text/x-adasrc'], + 'adts' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'], + 'aep' => ['application/vnd.audiograph'], + 'afm' => ['application/x-font-afm', 'application/x-font-type1'], + 'afp' => ['application/vnd.ibm.modcap'], + 'ag' => ['image/x-applix-graphics'], + 'agb' => ['application/x-gba-rom'], + 'age' => ['application/vnd.age'], + 'ahead' => ['application/vnd.ahead.space'], + 'ai' => ['application/illustrator', 'application/postscript', 'application/vnd.adobe.illustrator'], + 'aif' => ['audio/x-aiff'], + 'aifc' => ['audio/x-aifc', 'audio/x-aiff', 'audio/x-aiffc'], + 'aiff' => ['audio/x-aiff'], + 'aiffc' => ['audio/x-aifc', 'audio/x-aiffc'], + 'air' => ['application/vnd.adobe.air-application-installer-package+zip'], + 'ait' => ['application/vnd.dvb.ait'], + 'al' => ['application/x-perl', 'text/x-perl'], + 'alz' => ['application/x-alz'], + 'ami' => ['application/vnd.amiga.ami'], + 'amr' => ['audio/amr', 'audio/amr-encrypted'], + 'amz' => ['audio/x-amzxml'], + 'ani' => ['application/x-navi-animation'], + 'anim1' => ['video/x-anim'], + 'anim2' => ['video/x-anim'], + 'anim3' => ['video/x-anim'], + 'anim4' => ['video/x-anim'], + 'anim5' => ['video/x-anim'], + 'anim6' => ['video/x-anim'], + 'anim7' => ['video/x-anim'], + 'anim8' => ['video/x-anim'], + 'anim9' => ['video/x-anim'], + 'animj' => ['video/x-anim'], + 'anx' => ['application/annodex', 'application/x-annodex'], + 'ape' => ['audio/x-ape'], + 'apk' => ['application/vnd.android.package-archive'], + 'apng' => ['image/apng', 'image/vnd.mozilla.apng'], + 'appcache' => ['text/cache-manifest'], + 'appimage' => ['application/vnd.appimage', 'application/x-iso9660-appimage'], + 'application' => ['application/x-ms-application'], + 'apr' => ['application/vnd.lotus-approach'], + 'ar' => ['application/x-archive'], + 'arc' => ['application/x-freearc'], + 'arj' => ['application/x-arj'], + 'arw' => ['image/x-sony-arw'], + 'as' => ['application/x-applix-spreadsheet'], + 'asar' => ['application/x-asar'], + 'asc' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature', 'text/plain'], + 'asd' => ['text/x-common-lisp'], + 'asf' => ['application/vnd.ms-asf', 'video/x-ms-asf', 'video/x-ms-asf-plugin', 'video/x-ms-wm'], + 'asice' => ['application/vnd.etsi.asic-e+zip'], + 'asm' => ['text/x-asm'], + 'aso' => ['application/vnd.accpac.simply.aso'], + 'asp' => ['application/x-asp'], + 'ass' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts', 'text/x-ssa'], + 'astc' => ['image/astc'], + 'asx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-asf', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'], + 'atc' => ['application/vnd.acucorp'], + 'atom' => ['application/atom+xml'], + 'atomcat' => ['application/atomcat+xml'], + 'atomdeleted' => ['application/atomdeleted+xml'], + 'atomsvc' => ['application/atomsvc+xml'], + 'atx' => ['application/vnd.antix.game-component'], + 'au' => ['audio/basic'], + 'automount' => ['text/x-systemd-unit'], + 'avci' => ['image/avci'], + 'avcs' => ['image/avcs'], + 'avf' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.avi', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'], + 'avi' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.avi', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'], + 'avif' => ['image/avif', 'image/avif-sequence'], + 'avifs' => ['image/avif', 'image/avif-sequence'], + 'aw' => ['application/applixware', 'application/x-applix-word'], + 'awb' => ['audio/amr-wb', 'audio/amr-wb-encrypted'], + 'awk' => ['application/x-awk'], + 'axa' => ['audio/annodex', 'audio/x-annodex'], + 'axv' => ['video/annodex', 'video/x-annodex'], + 'azf' => ['application/vnd.airzip.filesecure.azf'], + 'azs' => ['application/vnd.airzip.filesecure.azs'], + 'azv' => ['image/vnd.airzip.accelerator.azv'], + 'azw' => ['application/vnd.amazon.ebook'], + 'azw3' => ['application/vnd.amazon.mobi8-ebook', 'application/x-mobi8-ebook'], + 'b16' => ['image/vnd.pco.b16'], + 'bak' => ['application/x-trash'], + 'bat' => ['application/bat', 'application/x-bat', 'application/x-msdownload'], + 'bcpio' => ['application/x-bcpio'], + 'bdf' => ['application/x-font-bdf'], + 'bdm' => ['application/vnd.syncml.dm+wbxml', 'video/mp2t'], + 'bdmv' => ['video/mp2t'], + 'bdoc' => ['application/bdoc', 'application/x-bdoc'], + 'bed' => ['application/vnd.realvnc.bed'], + 'bh2' => ['application/vnd.fujitsu.oasysprs'], + 'bib' => ['text/x-bibtex'], + 'bik' => ['video/vnd.radgamettools.bink'], + 'bin' => ['application/octet-stream'], + 'bk2' => ['video/vnd.radgamettools.bink'], + 'blb' => ['application/x-blorb'], + 'blend' => ['application/x-blender'], + 'blender' => ['application/x-blender'], + 'blorb' => ['application/x-blorb'], + 'blp' => ['text/x-blueprint'], + 'bmi' => ['application/vnd.bmi'], + 'bmml' => ['application/vnd.balsamiq.bmml+xml'], + 'bmp' => ['image/bmp', 'image/x-bmp', 'image/x-ms-bmp'], + 'book' => ['application/vnd.framemaker'], + 'box' => ['application/vnd.previewsystems.box'], + 'boz' => ['application/x-bzip2'], + 'bps' => ['application/x-bps-patch'], + 'bsdiff' => ['application/x-bsdiff'], + 'bsp' => ['model/vnd.valve.source.compiled-map'], + 'btif' => ['image/prs.btif'], + 'bz' => ['application/bzip2', 'application/x-bzip'], + 'bz2' => ['application/x-bz2', 'application/bzip2', 'application/x-bzip2'], + 'bz3' => ['application/x-bzip3'], + 'c' => ['text/x-c', 'text/x-csrc'], + 'c++' => ['text/x-c++src'], + 'c11amc' => ['application/vnd.cluetrust.cartomobile-config'], + 'c11amz' => ['application/vnd.cluetrust.cartomobile-config-pkg'], + 'c4d' => ['application/vnd.clonk.c4group'], + 'c4f' => ['application/vnd.clonk.c4group'], + 'c4g' => ['application/vnd.clonk.c4group'], + 'c4p' => ['application/vnd.clonk.c4group'], + 'c4u' => ['application/vnd.clonk.c4group'], + 'cab' => ['application/vnd.ms-cab-compressed', 'zz-application/zz-winassoc-cab'], + 'caf' => ['audio/x-caf'], + 'cap' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'], + 'car' => ['application/vnd.curl.car'], + 'cat' => ['application/vnd.ms-pki.seccat'], + 'cb7' => ['application/x-cb7', 'application/x-cbr'], + 'cba' => ['application/x-cbr'], + 'cbl' => ['text/x-cobol'], + 'cbor' => ['application/cbor'], + 'cbr' => ['application/vnd.comicbook-rar', 'application/x-cbr'], + 'cbt' => ['application/x-cbr', 'application/x-cbt'], + 'cbz' => ['application/vnd.comicbook+zip', 'application/x-cbr', 'application/x-cbz'], + 'cc' => ['text/x-c', 'text/x-c++src'], + 'cci' => ['application/x-nintendo-3ds-rom'], + 'ccmx' => ['application/x-ccmx'], + 'cco' => ['application/x-cocoa'], + 'cct' => ['application/x-director'], + 'ccxml' => ['application/ccxml+xml'], + 'cdbcmsg' => ['application/vnd.contact.cmsg'], + 'cdf' => ['application/x-netcdf'], + 'cdfx' => ['application/cdfx+xml'], + 'cdi' => ['application/x-discjuggler-cd-image'], + 'cdkey' => ['application/vnd.mediastation.cdkey'], + 'cdmia' => ['application/cdmi-capability'], + 'cdmic' => ['application/cdmi-container'], + 'cdmid' => ['application/cdmi-domain'], + 'cdmio' => ['application/cdmi-object'], + 'cdmiq' => ['application/cdmi-queue'], + 'cdr' => ['application/cdr', 'application/coreldraw', 'application/vnd.corel-draw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'], + 'cdx' => ['chemical/x-cdx'], + 'cdxml' => ['application/vnd.chemdraw+xml'], + 'cdy' => ['application/vnd.cinderella'], + 'cer' => ['application/pkix-cert'], + 'cert' => ['application/x-x509-ca-cert'], + 'cfs' => ['application/x-cfs-compressed'], + 'cgb' => ['application/x-gameboy-color-rom'], + 'cgm' => ['image/cgm'], + 'chat' => ['application/x-chat'], + 'chd' => ['application/x-mame-chd'], + 'chm' => ['application/vnd.ms-htmlhelp', 'application/x-chm'], + 'chrt' => ['application/vnd.kde.kchart', 'application/x-kchart'], + 'cif' => ['chemical/x-cif'], + 'cii' => ['application/vnd.anser-web-certificate-issue-initiation'], + 'cil' => ['application/vnd.ms-artgalry'], + 'cjs' => ['application/node'], + 'cl' => ['text/x-opencl-src'], + 'cla' => ['application/vnd.claymore'], + 'class' => ['application/java', 'application/java-byte-code', 'application/java-vm', 'application/x-java', 'application/x-java-class', 'application/x-java-vm'], + 'clkk' => ['application/vnd.crick.clicker.keyboard'], + 'clkp' => ['application/vnd.crick.clicker.palette'], + 'clkt' => ['application/vnd.crick.clicker.template'], + 'clkw' => ['application/vnd.crick.clicker.wordbank'], + 'clkx' => ['application/vnd.crick.clicker'], + 'clp' => ['application/x-msclip'], + 'clpi' => ['video/mp2t'], + 'cls' => ['application/x-tex', 'text/x-tex'], + 'cmake' => ['text/x-cmake'], + 'cmc' => ['application/vnd.cosmocaller'], + 'cmdf' => ['chemical/x-cmdf'], + 'cml' => ['chemical/x-cml'], + 'cmp' => ['application/vnd.yellowriver-custom-menu'], + 'cmx' => ['image/x-cmx'], + 'cob' => ['text/x-cobol'], + 'cod' => ['application/vnd.rim.cod'], + 'coffee' => ['application/vnd.coffeescript', 'text/coffeescript'], + 'com' => ['application/x-msdownload'], + 'conf' => ['text/plain'], + 'cpi' => ['video/mp2t'], + 'cpio' => ['application/x-cpio'], + 'cpio.gz' => ['application/x-cpio-compressed'], + 'cpl' => ['application/cpl+xml'], + 'cpp' => ['text/x-c', 'text/x-c++src'], + 'cpt' => ['application/mac-compactpro'], + 'cr' => ['text/crystal', 'text/x-crystal'], + 'cr2' => ['image/x-canon-cr2'], + 'cr3' => ['image/x-canon-cr3'], + 'crd' => ['application/x-mscardfile'], + 'crdownload' => ['application/x-partial-download'], + 'crl' => ['application/pkix-crl'], + 'crt' => ['application/x-x509-ca-cert'], + 'crw' => ['image/x-canon-crw'], + 'crx' => ['application/x-chrome-extension'], + 'cryptonote' => ['application/vnd.rig.cryptonote'], + 'cs' => ['text/x-csharp'], + 'csh' => ['application/x-csh'], + 'csl' => ['application/vnd.citationstyles.style+xml'], + 'csml' => ['chemical/x-csml'], + 'cso' => ['application/x-compressed-iso'], + 'csp' => ['application/vnd.commonspace'], + 'css' => ['text/css'], + 'cst' => ['application/x-director'], + 'csv' => ['text/csv', 'application/csv', 'text/x-comma-separated-values', 'text/x-csv'], + 'csvs' => ['text/csv-schema'], + 'cu' => ['application/cu-seeme'], + 'cue' => ['application/x-cue'], + 'cur' => ['image/x-win-bitmap'], + 'curl' => ['text/vnd.curl'], + 'cwk' => ['application/x-appleworks-document'], + 'cww' => ['application/prs.cww'], + 'cxt' => ['application/x-director'], + 'cxx' => ['text/x-c', 'text/x-c++src'], + 'd' => ['text/x-dsrc'], + 'dae' => ['model/vnd.collada+xml'], + 'daf' => ['application/vnd.mobius.daf'], + 'dar' => ['application/x-dar'], + 'dart' => ['application/vnd.dart', 'text/x-dart'], + 'dataless' => ['application/vnd.fdsn.seed'], + 'davmount' => ['application/davmount+xml'], + 'dbf' => ['application/dbase', 'application/dbf', 'application/vnd.dbf', 'application/x-dbase', 'application/x-dbf'], + 'dbk' => ['application/docbook+xml', 'application/vnd.oasis.docbook+xml', 'application/x-docbook+xml'], + 'dc' => ['application/x-dc-rom'], + 'dcl' => ['text/x-dcl'], + 'dcm' => ['application/dicom'], + 'dcr' => ['application/x-director', 'image/x-kodak-dcr'], + 'dcurl' => ['text/vnd.curl.dcurl'], + 'dd2' => ['application/vnd.oma.dd2+xml'], + 'ddd' => ['application/vnd.fujixerox.ddd'], + 'ddf' => ['application/vnd.syncml.dmddf+xml'], + 'dds' => ['image/vnd.ms-dds', 'image/x-dds'], + 'deb' => ['application/vnd.debian.binary-package', 'application/x-deb', 'application/x-debian-package'], + 'def' => ['text/plain'], + 'der' => ['application/x-x509-ca-cert'], + 'desktop' => ['application/x-desktop', 'application/x-gnome-app-info'], + 'device' => ['text/x-systemd-unit'], + 'dfac' => ['application/vnd.dreamfactory'], + 'dff' => ['audio/dff', 'audio/x-dff'], + 'dgc' => ['application/x-dgc-compressed'], + 'di' => ['text/x-dsrc'], + 'dia' => ['application/x-dia-diagram'], + 'dib' => ['image/bmp', 'image/x-bmp', 'image/x-ms-bmp'], + 'dic' => ['text/x-c'], + 'diff' => ['text/x-diff', 'text/x-patch'], + 'dir' => ['application/x-director'], + 'dis' => ['application/vnd.mobius.dis'], + 'disposition-notification' => ['message/disposition-notification'], + 'divx' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.avi', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'], + 'djv' => ['image/vnd.djvu', 'image/vnd.djvu+multipage', 'image/x-djvu', 'image/x.djvu'], + 'djvu' => ['image/vnd.djvu', 'image/vnd.djvu+multipage', 'image/x-djvu', 'image/x.djvu'], + 'dll' => ['application/x-msdownload'], + 'dmg' => ['application/x-apple-diskimage'], + 'dmp' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'], + 'dna' => ['application/vnd.dna'], + 'dng' => ['image/x-adobe-dng'], + 'doc' => ['application/msword', 'application/vnd.ms-word', 'application/x-msword', 'zz-application/zz-winassoc-doc'], + 'docbook' => ['application/docbook+xml', 'application/vnd.oasis.docbook+xml', 'application/x-docbook+xml'], + 'docm' => ['application/vnd.ms-word.document.macroenabled.12'], + 'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'], + 'dot' => ['application/msword', 'application/msword-template', 'text/vnd.graphviz'], + 'dotm' => ['application/vnd.ms-word.template.macroenabled.12'], + 'dotx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.template'], + 'dp' => ['application/vnd.osgi.dp'], + 'dpg' => ['application/vnd.dpgraph'], + 'dra' => ['audio/vnd.dra'], + 'drl' => ['application/x-excellon'], + 'drle' => ['image/dicom-rle'], + 'dsc' => ['text/prs.lines.tag'], + 'dsf' => ['audio/dsd', 'audio/dsf', 'audio/x-dsd', 'audio/x-dsf'], + 'dsl' => ['text/x-dsl'], + 'dssc' => ['application/dssc+der'], + 'dtb' => ['application/x-dtbook+xml', 'text/x-devicetree-binary'], + 'dtd' => ['application/xml-dtd', 'text/x-dtd'], + 'dts' => ['audio/vnd.dts', 'audio/x-dts', 'text/x-devicetree-source'], + 'dtshd' => ['audio/vnd.dts.hd', 'audio/x-dtshd'], + 'dtsi' => ['text/x-devicetree-source'], + 'dtx' => ['application/x-tex', 'text/x-tex'], + 'dv' => ['video/dv'], + 'dvb' => ['video/vnd.dvb.file'], + 'dvi' => ['application/x-dvi'], + 'dvi.bz2' => ['application/x-bzdvi'], + 'dvi.gz' => ['application/x-gzdvi'], + 'dwd' => ['application/atsc-dwd+xml'], + 'dwf' => ['model/vnd.dwf'], + 'dwg' => ['image/vnd.dwg'], + 'dxf' => ['image/vnd.dxf'], + 'dxp' => ['application/vnd.spotfire.dxp'], + 'dxr' => ['application/x-director'], + 'e' => ['text/x-eiffel'], + 'ear' => ['application/java-archive'], + 'ecelp4800' => ['audio/vnd.nuera.ecelp4800'], + 'ecelp7470' => ['audio/vnd.nuera.ecelp7470'], + 'ecelp9600' => ['audio/vnd.nuera.ecelp9600'], + 'ecma' => ['application/ecmascript'], + 'edm' => ['application/vnd.novadigm.edm'], + 'edx' => ['application/vnd.novadigm.edx'], + 'efif' => ['application/vnd.picsel'], + 'egon' => ['application/x-egon'], + 'ei6' => ['application/vnd.pg.osasli'], + 'eif' => ['text/x-eiffel'], + 'el' => ['text/x-emacs-lisp'], + 'emf' => ['application/emf', 'application/x-emf', 'application/x-msmetafile', 'image/emf', 'image/x-emf'], + 'eml' => ['message/rfc822'], + 'emma' => ['application/emma+xml'], + 'emotionml' => ['application/emotionml+xml'], + 'emp' => ['application/vnd.emusic-emusic_package'], + 'emz' => ['application/x-msmetafile'], + 'ent' => ['application/xml-external-parsed-entity', 'text/xml-external-parsed-entity'], + 'eol' => ['audio/vnd.digital-winds'], + 'eot' => ['application/vnd.ms-fontobject'], + 'eps' => ['application/postscript', 'image/x-eps'], + 'eps.bz2' => ['image/x-bzeps'], + 'eps.gz' => ['image/x-gzeps'], + 'epsf' => ['image/x-eps'], + 'epsf.bz2' => ['image/x-bzeps'], + 'epsf.gz' => ['image/x-gzeps'], + 'epsi' => ['image/x-eps'], + 'epsi.bz2' => ['image/x-bzeps'], + 'epsi.gz' => ['image/x-gzeps'], + 'epub' => ['application/epub+zip'], + 'eris' => ['application/x-eris-link+cbor'], + 'erl' => ['text/x-erlang'], + 'es' => ['application/ecmascript', 'text/ecmascript'], + 'es3' => ['application/vnd.eszigno3+xml'], + 'esa' => ['application/vnd.osgi.subsystem'], + 'escn' => ['application/x-godot-scene'], + 'esf' => ['application/vnd.epson.esf'], + 'et3' => ['application/vnd.eszigno3+xml'], + 'etheme' => ['application/x-e-theme'], + 'etx' => ['text/x-setext'], + 'eva' => ['application/x-eva'], + 'evy' => ['application/x-envoy'], + 'ex' => ['text/x-elixir'], + 'exe' => ['application/x-ms-dos-executable', 'application/x-msdos-program', 'application/x-msdownload'], + 'exi' => ['application/exi'], + 'exp' => ['application/express'], + 'exr' => ['image/aces', 'image/x-exr'], + 'exs' => ['text/x-elixir'], + 'ext' => ['application/vnd.novadigm.ext'], + 'ez' => ['application/andrew-inset'], + 'ez2' => ['application/vnd.ezpix-album'], + 'ez3' => ['application/vnd.ezpix-package'], + 'f' => ['text/x-fortran'], + 'f4a' => ['audio/m4a', 'audio/mp4', 'audio/x-m4a'], + 'f4b' => ['audio/x-m4b'], + 'f4v' => ['video/mp4', 'video/mp4v-es', 'video/x-f4v', 'video/x-m4v'], + 'f77' => ['text/x-fortran'], + 'f90' => ['text/x-fortran'], + 'f95' => ['text/x-fortran'], + 'fasl' => ['text/x-common-lisp'], + 'fb2' => ['application/x-fictionbook', 'application/x-fictionbook+xml'], + 'fb2.zip' => ['application/x-zip-compressed-fb2'], + 'fbs' => ['image/vnd.fastbidsheet'], + 'fcdt' => ['application/vnd.adobe.formscentral.fcdt'], + 'fcs' => ['application/vnd.isac.fcs'], + 'fd' => ['application/x-fd-file', 'application/x-raw-floppy-disk-image'], + 'fdf' => ['application/vnd.fdf'], + 'fds' => ['application/x-fds-disk'], + 'fdt' => ['application/fdt+xml'], + 'fe_launch' => ['application/vnd.denovo.fcselayout-link'], + 'feature' => ['text/x-gherkin'], + 'fg5' => ['application/vnd.fujitsu.oasysgp'], + 'fgd' => ['application/x-director'], + 'fh' => ['image/x-freehand'], + 'fh4' => ['image/x-freehand'], + 'fh5' => ['image/x-freehand'], + 'fh7' => ['image/x-freehand'], + 'fhc' => ['image/x-freehand'], + 'fig' => ['application/x-xfig', 'image/x-xfig'], + 'fish' => ['application/x-fishscript', 'text/x-fish'], + 'fit' => ['application/fits', 'image/fits', 'image/x-fits'], + 'fits' => ['application/fits', 'image/fits', 'image/x-fits'], + 'fl' => ['application/x-fluid'], + 'flac' => ['audio/flac', 'audio/x-flac'], + 'flatpak' => ['application/vnd.flatpak', 'application/vnd.xdgapp'], + 'flatpakref' => ['application/vnd.flatpak.ref'], + 'flatpakrepo' => ['application/vnd.flatpak.repo'], + 'flc' => ['video/fli', 'video/x-fli', 'video/x-flic'], + 'fli' => ['video/fli', 'video/x-fli', 'video/x-flic'], + 'flo' => ['application/vnd.micrografx.flo'], + 'flv' => ['video/x-flv', 'application/x-flash-video', 'flv-application/octet-stream', 'video/flv'], + 'flw' => ['application/vnd.kde.kivio', 'application/x-kivio'], + 'flx' => ['text/vnd.fmi.flexstor'], + 'fly' => ['text/vnd.fly'], + 'fm' => ['application/vnd.framemaker', 'application/x-frame'], + 'fnc' => ['application/vnd.frogans.fnc'], + 'fo' => ['application/vnd.software602.filler.form+xml', 'text/x-xslfo'], + 'fodg' => ['application/vnd.oasis.opendocument.graphics-flat-xml'], + 'fodp' => ['application/vnd.oasis.opendocument.presentation-flat-xml'], + 'fods' => ['application/vnd.oasis.opendocument.spreadsheet-flat-xml'], + 'fodt' => ['application/vnd.oasis.opendocument.text-flat-xml'], + 'for' => ['text/x-fortran'], + 'fpx' => ['image/vnd.fpx'], + 'frame' => ['application/vnd.framemaker'], + 'fsc' => ['application/vnd.fsc.weblaunch'], + 'fst' => ['image/vnd.fst'], + 'ftc' => ['application/vnd.fluxtime.clip'], + 'fti' => ['application/vnd.anser-web-funds-transfer-initiation'], + 'fts' => ['application/fits', 'image/fits', 'image/x-fits'], + 'fvt' => ['video/vnd.fvt'], + 'fxm' => ['video/x-javafx'], + 'fxp' => ['application/vnd.adobe.fxp'], + 'fxpl' => ['application/vnd.adobe.fxp'], + 'fzs' => ['application/vnd.fuzzysheet'], + 'g2w' => ['application/vnd.geoplan'], + 'g3' => ['image/fax-g3', 'image/g3fax'], + 'g3w' => ['application/vnd.geospace'], + 'gac' => ['application/vnd.groove-account'], + 'gam' => ['application/x-tads'], + 'gb' => ['application/x-gameboy-rom'], + 'gba' => ['application/x-gba-rom'], + 'gbc' => ['application/x-gameboy-color-rom'], + 'gbr' => ['application/rpki-ghostbusters', 'application/vnd.gerber', 'application/x-gerber', 'image/x-gimp-gbr'], + 'gbrjob' => ['application/x-gerber-job'], + 'gca' => ['application/x-gca-compressed'], + 'gcode' => ['text/x.gcode'], + 'gcrd' => ['text/directory', 'text/vcard', 'text/x-vcard'], + 'gd' => ['application/x-gdscript'], + 'gdi' => ['application/x-gd-rom-cue'], + 'gdl' => ['model/vnd.gdl'], + 'gdoc' => ['application/vnd.google-apps.document'], + 'gdshader' => ['application/x-godot-shader'], + 'ged' => ['application/x-gedcom', 'text/gedcom', 'text/vnd.familysearch.gedcom'], + 'gedcom' => ['application/x-gedcom', 'text/gedcom', 'text/vnd.familysearch.gedcom'], + 'gem' => ['application/x-gtar', 'application/x-tar'], + 'gen' => ['application/x-genesis-rom'], + 'geo' => ['application/vnd.dynageo'], + 'geo.json' => ['application/geo+json', 'application/vnd.geo+json'], + 'geojson' => ['application/geo+json', 'application/vnd.geo+json'], + 'gex' => ['application/vnd.geometry-explorer'], + 'gf' => ['application/x-tex-gf'], + 'gg' => ['application/x-gamegear-rom'], + 'ggb' => ['application/vnd.geogebra.file'], + 'ggt' => ['application/vnd.geogebra.tool'], + 'ghf' => ['application/vnd.groove-help'], + 'gif' => ['image/gif'], + 'gih' => ['image/x-gimp-gih'], + 'gim' => ['application/vnd.groove-identity-message'], + 'glade' => ['application/x-glade'], + 'glb' => ['model/gltf-binary'], + 'gltf' => ['model/gltf+json'], + 'gml' => ['application/gml+xml'], + 'gmo' => ['application/x-gettext-translation'], + 'gmx' => ['application/vnd.gmx'], + 'gnc' => ['application/x-gnucash'], + 'gnd' => ['application/gnunet-directory'], + 'gnucash' => ['application/x-gnucash'], + 'gnumeric' => ['application/x-gnumeric'], + 'gnuplot' => ['application/x-gnuplot'], + 'go' => ['text/x-go'], + 'gp' => ['application/x-gnuplot'], + 'gpg' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature'], + 'gph' => ['application/vnd.flographit'], + 'gplt' => ['application/x-gnuplot'], + 'gpx' => ['application/gpx', 'application/gpx+xml', 'application/x-gpx', 'application/x-gpx+xml'], + 'gqf' => ['application/vnd.grafeq'], + 'gqs' => ['application/vnd.grafeq'], + 'gra' => ['application/x-graphite'], + 'gradle' => ['text/x-gradle'], + 'gram' => ['application/srgs'], + 'gramps' => ['application/x-gramps-xml'], + 'gre' => ['application/vnd.geometry-explorer'], + 'groovy' => ['text/x-groovy'], + 'grv' => ['application/vnd.groove-injector'], + 'grxml' => ['application/srgs+xml'], + 'gs' => ['text/x-genie'], + 'gsf' => ['application/x-font-ghostscript', 'application/x-font-type1'], + 'gsh' => ['text/x-groovy'], + 'gsheet' => ['application/vnd.google-apps.spreadsheet'], + 'gslides' => ['application/vnd.google-apps.presentation'], + 'gsm' => ['audio/x-gsm'], + 'gtar' => ['application/x-gtar', 'application/x-tar'], + 'gtm' => ['application/vnd.groove-tool-message'], + 'gtw' => ['model/vnd.gtw'], + 'gv' => ['text/vnd.graphviz'], + 'gvp' => ['text/google-video-pointer', 'text/x-google-video-pointer'], + 'gvy' => ['text/x-groovy'], + 'gx' => ['text/x-gcode-gx'], + 'gxf' => ['application/gxf'], + 'gxt' => ['application/vnd.geonext'], + 'gy' => ['text/x-groovy'], + 'gz' => ['application/x-gzip', 'application/gzip'], + 'h' => ['text/x-c', 'text/x-chdr'], + 'h++' => ['text/x-c++hdr'], + 'h261' => ['video/h261'], + 'h263' => ['video/h263'], + 'h264' => ['video/h264'], + 'h4' => ['application/x-hdf'], + 'h5' => ['application/x-hdf'], + 'hal' => ['application/vnd.hal+xml'], + 'hbci' => ['application/vnd.hbci'], + 'hbs' => ['text/x-handlebars-template'], + 'hdd' => ['application/x-virtualbox-hdd'], + 'hdf' => ['application/x-hdf'], + 'hdf4' => ['application/x-hdf'], + 'hdf5' => ['application/x-hdf'], + 'hdp' => ['image/jxr', 'image/vnd.ms-photo'], + 'heic' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'], + 'heics' => ['image/heic-sequence'], + 'heif' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'], + 'heifs' => ['image/heif-sequence'], + 'hej2' => ['image/hej2k'], + 'held' => ['application/atsc-held+xml'], + 'hfe' => ['application/x-hfe-file', 'application/x-hfe-floppy-image'], + 'hh' => ['text/x-c', 'text/x-c++hdr'], + 'hif' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'], + 'hjson' => ['application/hjson'], + 'hlp' => ['application/winhlp', 'zz-application/zz-winassoc-hlp'], + 'hp' => ['text/x-c++hdr'], + 'hpgl' => ['application/vnd.hp-hpgl'], + 'hpid' => ['application/vnd.hp-hpid'], + 'hpp' => ['text/x-c++hdr'], + 'hps' => ['application/vnd.hp-hps'], + 'hqx' => ['application/stuffit', 'application/mac-binhex40'], + 'hs' => ['text/x-haskell'], + 'hsj2' => ['image/hsj2'], + 'htc' => ['text/x-component'], + 'htke' => ['application/vnd.kenameaapp'], + 'htm' => ['text/html', 'application/xhtml+xml'], + 'html' => ['text/html', 'application/xhtml+xml'], + 'hvd' => ['application/vnd.yamaha.hv-dic'], + 'hvp' => ['application/vnd.yamaha.hv-voice'], + 'hvs' => ['application/vnd.yamaha.hv-script'], + 'hwp' => ['application/vnd.haansoft-hwp', 'application/x-hwp'], + 'hwt' => ['application/vnd.haansoft-hwt', 'application/x-hwt'], + 'hxx' => ['text/x-c++hdr'], + 'i2g' => ['application/vnd.intergeo'], + 'ica' => ['application/x-ica'], + 'icb' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'icc' => ['application/vnd.iccprofile'], + 'ice' => ['x-conference/x-cooltalk'], + 'icm' => ['application/vnd.iccprofile'], + 'icns' => ['image/x-icns'], + 'ico' => ['application/ico', 'image/ico', 'image/icon', 'image/vnd.microsoft.icon', 'image/x-ico', 'image/x-icon', 'text/ico'], + 'ics' => ['application/ics', 'text/calendar', 'text/x-vcalendar'], + 'idl' => ['text/x-idl'], + 'ief' => ['image/ief'], + 'ifb' => ['text/calendar'], + 'iff' => ['image/x-iff', 'image/x-ilbm'], + 'ifm' => ['application/vnd.shana.informed.formdata'], + 'iges' => ['model/iges'], + 'igl' => ['application/vnd.igloader'], + 'igm' => ['application/vnd.insors.igm'], + 'igs' => ['model/iges'], + 'igx' => ['application/vnd.micrografx.igx'], + 'iif' => ['application/vnd.shana.informed.interchange'], + 'ilbm' => ['image/x-iff', 'image/x-ilbm'], + 'ime' => ['audio/imelody', 'audio/x-imelody', 'text/x-imelody'], + 'img' => ['application/vnd.efi.img', 'application/x-raw-disk-image'], + 'img.xz' => ['application/x-raw-disk-image-xz-compressed'], + 'imp' => ['application/vnd.accpac.simply.imp'], + 'ims' => ['application/vnd.ms-ims'], + 'imy' => ['audio/imelody', 'audio/x-imelody', 'text/x-imelody'], + 'in' => ['text/plain'], + 'ini' => ['text/plain'], + 'ink' => ['application/inkml+xml'], + 'inkml' => ['application/inkml+xml'], + 'ins' => ['application/x-tex', 'text/x-tex'], + 'install' => ['application/x-install-instructions'], + 'iota' => ['application/vnd.astraea-software.iota'], + 'ipfix' => ['application/ipfix'], + 'ipk' => ['application/vnd.shana.informed.package'], + 'ips' => ['application/x-ips-patch'], + 'iptables' => ['text/x-iptables'], + 'ipynb' => ['application/x-ipynb+json'], + 'irm' => ['application/vnd.ibm.rights-management'], + 'irp' => ['application/vnd.irepository.package+xml'], + 'iso' => ['application/vnd.efi.iso', 'application/x-cd-image', 'application/x-dreamcast-rom', 'application/x-gamecube-iso-image', 'application/x-gamecube-rom', 'application/x-iso9660-image', 'application/x-saturn-rom', 'application/x-sega-cd-rom', 'application/x-sega-pico-rom', 'application/x-wbfs', 'application/x-wia', 'application/x-wii-iso-image', 'application/x-wii-rom'], + 'iso9660' => ['application/vnd.efi.iso', 'application/x-cd-image', 'application/x-iso9660-image'], + 'it' => ['audio/x-it'], + 'it87' => ['application/x-it87'], + 'itp' => ['application/vnd.shana.informed.formtemplate'], + 'its' => ['application/its+xml'], + 'ivp' => ['application/vnd.immervision-ivp'], + 'ivu' => ['application/vnd.immervision-ivu'], + 'j2c' => ['image/x-jp2-codestream'], + 'j2k' => ['image/x-jp2-codestream'], + 'jad' => ['text/vnd.sun.j2me.app-descriptor'], + 'jade' => ['text/jade'], + 'jam' => ['application/vnd.jam'], + 'jar' => ['application/x-java-archive', 'application/java-archive', 'application/x-jar'], + 'jardiff' => ['application/x-java-archive-diff'], + 'java' => ['text/x-java', 'text/x-java-source'], + 'jceks' => ['application/x-java-jce-keystore'], + 'jhc' => ['image/jphc'], + 'jisp' => ['application/vnd.jisp'], + 'jks' => ['application/x-java-keystore'], + 'jl' => ['text/julia'], + 'jls' => ['image/jls'], + 'jlt' => ['application/vnd.hp-jlyt'], + 'jng' => ['image/x-jng'], + 'jnlp' => ['application/x-java-jnlp-file'], + 'joda' => ['application/vnd.joost.joda-archive'], + 'jp2' => ['image/jp2', 'image/jpeg2000', 'image/jpeg2000-image', 'image/x-jpeg2000-image'], + 'jpc' => ['image/x-jp2-codestream'], + 'jpe' => ['image/jpeg', 'image/pjpeg'], + 'jpeg' => ['image/jpeg', 'image/pjpeg'], + 'jpf' => ['image/jpx'], + 'jpg' => ['image/jpeg', 'image/pjpeg'], + 'jpg2' => ['image/jp2', 'image/jpeg2000', 'image/jpeg2000-image', 'image/x-jpeg2000-image'], + 'jpgm' => ['image/jpm', 'video/jpm'], + 'jpgv' => ['video/jpeg'], + 'jph' => ['image/jph'], + 'jpm' => ['image/jpm', 'video/jpm'], + 'jpr' => ['application/x-jbuilder-project'], + 'jpx' => ['application/x-jbuilder-project', 'image/jpx'], + 'jrd' => ['application/jrd+json'], + 'js' => ['text/javascript', 'application/javascript', 'application/x-javascript'], + 'jsm' => ['application/javascript', 'application/x-javascript', 'text/javascript'], + 'json' => ['application/json', 'application/schema+json'], + 'json-patch' => ['application/json-patch+json'], + 'json5' => ['application/json5'], + 'jsonld' => ['application/ld+json'], + 'jsonml' => ['application/jsonml+json'], + 'jsx' => ['text/jsx'], + 'jxl' => ['image/jxl'], + 'jxr' => ['image/jxr', 'image/vnd.ms-photo'], + 'jxra' => ['image/jxra'], + 'jxrs' => ['image/jxrs'], + 'jxs' => ['image/jxs'], + 'jxsc' => ['image/jxsc'], + 'jxsi' => ['image/jxsi'], + 'jxss' => ['image/jxss'], + 'k25' => ['image/x-kodak-k25'], + 'k7' => ['application/x-thomson-cassette'], + 'kar' => ['audio/midi', 'audio/x-midi'], + 'karbon' => ['application/vnd.kde.karbon', 'application/x-karbon'], + 'kdbx' => ['application/x-keepass2'], + 'kdc' => ['image/x-kodak-kdc'], + 'kdelnk' => ['application/x-desktop', 'application/x-gnome-app-info'], + 'kexi' => ['application/x-kexiproject-sqlite', 'application/x-kexiproject-sqlite2', 'application/x-kexiproject-sqlite3', 'application/x-vnd.kde.kexi'], + 'kexic' => ['application/x-kexi-connectiondata'], + 'kexis' => ['application/x-kexiproject-shortcut'], + 'key' => ['application/vnd.apple.keynote', 'application/pgp-keys', 'application/x-iwork-keynote-sffkey'], + 'keynote' => ['application/vnd.apple.keynote'], + 'kfo' => ['application/vnd.kde.kformula', 'application/x-kformula'], + 'kfx' => ['application/vnd.amazon.mobi8-ebook', 'application/x-mobi8-ebook'], + 'kia' => ['application/vnd.kidspiration'], + 'kil' => ['application/x-killustrator'], + 'kino' => ['application/smil', 'application/smil+xml'], + 'kml' => ['application/vnd.google-earth.kml+xml'], + 'kmz' => ['application/vnd.google-earth.kmz'], + 'kne' => ['application/vnd.kinar'], + 'knp' => ['application/vnd.kinar'], + 'kon' => ['application/vnd.kde.kontour', 'application/x-kontour'], + 'kpm' => ['application/x-kpovmodeler'], + 'kpr' => ['application/vnd.kde.kpresenter', 'application/x-kpresenter'], + 'kpt' => ['application/vnd.kde.kpresenter', 'application/x-kpresenter'], + 'kpxx' => ['application/vnd.ds-keypoint'], + 'kra' => ['application/x-krita'], + 'krz' => ['application/x-krita'], + 'ks' => ['application/x-java-keystore'], + 'ksp' => ['application/vnd.kde.kspread', 'application/x-kspread'], + 'ksy' => ['text/x-kaitai-struct'], + 'kt' => ['text/x-kotlin'], + 'ktr' => ['application/vnd.kahootz'], + 'ktx' => ['image/ktx'], + 'ktx2' => ['image/ktx2'], + 'ktz' => ['application/vnd.kahootz'], + 'kud' => ['application/x-kugar'], + 'kwd' => ['application/vnd.kde.kword', 'application/x-kword'], + 'kwt' => ['application/vnd.kde.kword', 'application/x-kword'], + 'la' => ['application/x-shared-library-la'], + 'lasxml' => ['application/vnd.las.las+xml'], + 'latex' => ['application/x-latex', 'application/x-tex', 'text/x-tex'], + 'lbd' => ['application/vnd.llamagraphics.life-balance.desktop'], + 'lbe' => ['application/vnd.llamagraphics.life-balance.exchange+xml'], + 'lbm' => ['image/x-iff', 'image/x-ilbm'], + 'ldif' => ['text/x-ldif'], + 'les' => ['application/vnd.hhe.lesson-player'], + 'less' => ['text/less'], + 'lgr' => ['application/lgr+xml'], + 'lha' => ['application/x-lha', 'application/x-lzh-compressed'], + 'lhs' => ['text/x-literate-haskell'], + 'lhz' => ['application/x-lhz'], + 'link66' => ['application/vnd.route66.link66+xml'], + 'lisp' => ['text/x-common-lisp'], + 'list' => ['text/plain'], + 'list3820' => ['application/vnd.ibm.modcap'], + 'listafp' => ['application/vnd.ibm.modcap'], + 'litcoffee' => ['text/coffeescript'], + 'lmdb' => ['application/x-lmdb'], + 'lnk' => ['application/x-ms-shortcut'], + 'lnx' => ['application/x-atari-lynx-rom'], + 'loas' => ['audio/usac'], + 'log' => ['text/plain', 'text/x-log'], + 'lostxml' => ['application/lost+xml'], + 'lrm' => ['application/vnd.ms-lrm'], + 'lrv' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'], + 'lrz' => ['application/x-lrzip'], + 'ltf' => ['application/vnd.frogans.ltf'], + 'ltx' => ['application/x-tex', 'text/x-tex'], + 'lua' => ['text/x-lua'], + 'luac' => ['application/x-lua-bytecode'], + 'lvp' => ['audio/vnd.lucent.voice'], + 'lwo' => ['image/x-lwo'], + 'lwob' => ['image/x-lwo'], + 'lwp' => ['application/vnd.lotus-wordpro'], + 'lws' => ['image/x-lws'], + 'ly' => ['text/x-lilypond'], + 'lyx' => ['application/x-lyx', 'text/x-lyx'], + 'lz' => ['application/x-lzip'], + 'lz4' => ['application/x-lz4'], + 'lzh' => ['application/x-lha', 'application/x-lzh-compressed'], + 'lzma' => ['application/x-lzma'], + 'lzo' => ['application/x-lzop'], + 'm' => ['text/x-matlab', 'text/x-objcsrc', 'text/x-octave'], + 'm13' => ['application/x-msmediaview'], + 'm14' => ['application/x-msmediaview'], + 'm15' => ['audio/x-mod'], + 'm1u' => ['video/vnd.mpegurl', 'video/x-mpegurl'], + 'm1v' => ['video/mpeg'], + 'm21' => ['application/mp21'], + 'm2a' => ['audio/mpeg'], + 'm2t' => ['video/mp2t'], + 'm2ts' => ['video/mp2t'], + 'm2v' => ['video/mpeg'], + 'm3a' => ['audio/mpeg'], + 'm3u' => ['audio/x-mpegurl', 'application/m3u', 'application/vnd.apple.mpegurl', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist'], + 'm3u8' => ['application/m3u', 'application/vnd.apple.mpegurl', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist', 'audio/x-mpegurl'], + 'm4' => ['application/x-m4'], + 'm4a' => ['audio/mp4', 'audio/m4a', 'audio/x-m4a'], + 'm4b' => ['audio/x-m4b'], + 'm4p' => ['application/mp4'], + 'm4r' => ['audio/x-m4r'], + 'm4s' => ['video/iso.segment'], + 'm4u' => ['video/vnd.mpegurl', 'video/x-mpegurl'], + 'm4v' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'], + 'm7' => ['application/x-thomson-cartridge-memo7'], + 'ma' => ['application/mathematica'], + 'mab' => ['application/x-markaby'], + 'mads' => ['application/mads+xml'], + 'maei' => ['application/mmt-aei+xml'], + 'mag' => ['application/vnd.ecowin.chart'], + 'mak' => ['text/x-makefile'], + 'maker' => ['application/vnd.framemaker'], + 'man' => ['application/x-troff-man', 'text/troff'], + 'manifest' => ['text/cache-manifest'], + 'map' => ['application/json'], + 'markdown' => ['text/markdown', 'text/x-markdown'], + 'mathml' => ['application/mathml+xml'], + 'mb' => ['application/mathematica'], + 'mbk' => ['application/vnd.mobius.mbk'], + 'mbox' => ['application/mbox'], + 'mc1' => ['application/vnd.medcalcdata'], + 'mc2' => ['text/vnd.senx.warpscript'], + 'mcd' => ['application/vnd.mcd'], + 'mcurl' => ['text/vnd.curl.mcurl'], + 'md' => ['text/markdown', 'text/x-markdown'], + 'mdb' => ['application/x-msaccess', 'application/mdb', 'application/msaccess', 'application/vnd.ms-access', 'application/vnd.msaccess', 'application/x-lmdb', 'application/x-mdb', 'zz-application/zz-winassoc-mdb'], + 'mdi' => ['image/vnd.ms-modi'], + 'mdx' => ['application/x-genesis-32x-rom', 'text/mdx'], + 'me' => ['text/troff', 'text/x-troff-me'], + 'med' => ['audio/x-mod'], + 'mesh' => ['model/mesh'], + 'meta4' => ['application/metalink4+xml'], + 'metalink' => ['application/metalink+xml'], + 'mets' => ['application/mets+xml'], + 'mfm' => ['application/vnd.mfmp'], + 'mft' => ['application/rpki-manifest'], + 'mgp' => ['application/vnd.osgeo.mapguide.package', 'application/x-magicpoint'], + 'mgz' => ['application/vnd.proteus.magazine'], + 'mht' => ['application/x-mimearchive'], + 'mhtml' => ['application/x-mimearchive'], + 'mid' => ['audio/midi', 'audio/x-midi'], + 'midi' => ['audio/midi', 'audio/x-midi'], + 'mie' => ['application/x-mie'], + 'mif' => ['application/vnd.mif', 'application/x-mif'], + 'mime' => ['message/rfc822'], + 'minipsf' => ['audio/x-minipsf'], + 'mj2' => ['video/mj2'], + 'mjp2' => ['video/mj2'], + 'mjpeg' => ['video/x-mjpeg'], + 'mjpg' => ['video/x-mjpeg'], + 'mjs' => ['application/javascript', 'application/x-javascript', 'text/javascript'], + 'mk' => ['text/x-makefile'], + 'mk3d' => ['video/x-matroska', 'video/x-matroska-3d'], + 'mka' => ['audio/x-matroska'], + 'mkd' => ['text/markdown', 'text/x-markdown'], + 'mks' => ['video/x-matroska'], + 'mkv' => ['video/x-matroska'], + 'ml' => ['text/x-ocaml'], + 'mli' => ['text/x-ocaml'], + 'mlp' => ['application/vnd.dolby.mlp'], + 'mm' => ['text/x-objc++src', 'text/x-troff-mm'], + 'mmd' => ['application/vnd.chipnuts.karaoke-mmd'], + 'mmf' => ['application/vnd.smaf', 'application/x-smaf'], + 'mml' => ['application/mathml+xml', 'text/mathml'], + 'mmr' => ['image/vnd.fujixerox.edmics-mmr'], + 'mng' => ['video/x-mng'], + 'mny' => ['application/x-msmoney'], + 'mo' => ['application/x-gettext-translation', 'text/x-modelica'], + 'mo3' => ['audio/x-mo3'], + 'mobi' => ['application/x-mobipocket-ebook'], + 'moc' => ['text/x-moc'], + 'mod' => ['application/x-object', 'audio/x-mod'], + 'mods' => ['application/mods+xml'], + 'mof' => ['text/x-mof'], + 'moov' => ['video/quicktime'], + 'mount' => ['text/x-systemd-unit'], + 'mov' => ['video/quicktime'], + 'movie' => ['video/x-sgi-movie'], + 'mp+' => ['audio/x-musepack'], + 'mp2' => ['audio/mp2', 'audio/mpeg', 'audio/x-mp2', 'video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'], + 'mp21' => ['application/mp21'], + 'mp2a' => ['audio/mpeg'], + 'mp3' => ['audio/mpeg', 'audio/mp3', 'audio/x-mp3', 'audio/x-mpeg', 'audio/x-mpg'], + 'mp4' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'], + 'mp4a' => ['audio/mp4'], + 'mp4s' => ['application/mp4'], + 'mp4v' => ['video/mp4'], + 'mpc' => ['application/vnd.mophun.certificate', 'audio/x-musepack'], + 'mpd' => ['application/dash+xml'], + 'mpe' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'], + 'mpeg' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'], + 'mpf' => ['application/media-policy-dataset+xml'], + 'mpg' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'], + 'mpg4' => ['video/mp4'], + 'mpga' => ['audio/mp3', 'audio/mpeg', 'audio/x-mp3', 'audio/x-mpeg', 'audio/x-mpg'], + 'mpkg' => ['application/vnd.apple.installer+xml'], + 'mpl' => ['text/x-mpl2', 'video/mp2t'], + 'mpls' => ['video/mp2t'], + 'mpm' => ['application/vnd.blueice.multipass'], + 'mpn' => ['application/vnd.mophun.application'], + 'mpp' => ['application/dash-patch+xml', 'application/vnd.ms-project', 'audio/x-musepack'], + 'mpt' => ['application/vnd.ms-project'], + 'mpy' => ['application/vnd.ibm.minipay'], + 'mqy' => ['application/vnd.mobius.mqy'], + 'mrc' => ['application/marc'], + 'mrcx' => ['application/marcxml+xml'], + 'mrl' => ['text/x-mrml'], + 'mrml' => ['text/x-mrml'], + 'mrpack' => ['application/x-modrinth-modpack+zip'], + 'mrw' => ['image/x-minolta-mrw'], + 'ms' => ['text/troff', 'text/x-troff-ms'], + 'mscml' => ['application/mediaservercontrol+xml'], + 'mseed' => ['application/vnd.fdsn.mseed'], + 'mseq' => ['application/vnd.mseq'], + 'msf' => ['application/vnd.epson.msf'], + 'msg' => ['application/vnd.ms-outlook'], + 'msh' => ['model/mesh'], + 'msi' => ['application/x-msdownload', 'application/x-msi'], + 'msl' => ['application/vnd.mobius.msl'], + 'msod' => ['image/x-msod'], + 'msty' => ['application/vnd.muvee.style'], + 'msx' => ['application/x-msx-rom'], + 'mtl' => ['model/mtl'], + 'mtm' => ['audio/x-mod'], + 'mts' => ['model/vnd.mts', 'video/mp2t'], + 'mup' => ['text/x-mup'], + 'mus' => ['application/vnd.musician'], + 'musd' => ['application/mmt-usd+xml'], + 'musicxml' => ['application/vnd.recordare.musicxml+xml'], + 'mvb' => ['application/x-msmediaview'], + 'mvt' => ['application/vnd.mapbox-vector-tile'], + 'mwf' => ['application/vnd.mfer'], + 'mxf' => ['application/mxf'], + 'mxl' => ['application/vnd.recordare.musicxml'], + 'mxmf' => ['audio/mobile-xmf', 'audio/vnd.nokia.mobile-xmf'], + 'mxml' => ['application/xv+xml'], + 'mxs' => ['application/vnd.triscape.mxs'], + 'mxu' => ['video/vnd.mpegurl', 'video/x-mpegurl'], + 'n-gage' => ['application/vnd.nokia.n-gage.symbian.install'], + 'n3' => ['text/n3'], + 'n64' => ['application/x-n64-rom'], + 'nb' => ['application/mathematica', 'application/x-mathematica'], + 'nbp' => ['application/vnd.wolfram.player'], + 'nc' => ['application/x-netcdf'], + 'ncx' => ['application/x-dtbncx+xml'], + 'nds' => ['application/x-nintendo-ds-rom'], + 'nef' => ['image/x-nikon-nef'], + 'nes' => ['application/x-nes-rom'], + 'nez' => ['application/x-nes-rom'], + 'nfo' => ['text/x-nfo'], + 'ngc' => ['application/x-neo-geo-pocket-color-rom'], + 'ngdat' => ['application/vnd.nokia.n-gage.data'], + 'ngp' => ['application/x-neo-geo-pocket-rom'], + 'nim' => ['text/x-nim'], + 'nimble' => ['text/x-nimscript'], + 'nims' => ['text/x-nimscript'], + 'nitf' => ['application/vnd.nitf'], + 'nlu' => ['application/vnd.neurolanguage.nlu'], + 'nml' => ['application/vnd.enliven'], + 'nnd' => ['application/vnd.noblenet-directory'], + 'nns' => ['application/vnd.noblenet-sealer'], + 'nnw' => ['application/vnd.noblenet-web'], + 'not' => ['text/x-mup'], + 'npx' => ['image/vnd.net-fpx'], + 'nq' => ['application/n-quads'], + 'nrw' => ['image/x-nikon-nrw'], + 'nsc' => ['application/x-conference', 'application/x-netshow-channel'], + 'nsf' => ['application/vnd.lotus-notes'], + 'nsv' => ['video/x-nsv'], + 'nt' => ['application/n-triples'], + 'ntf' => ['application/vnd.nitf'], + 'nu' => ['application/x-nuscript', 'text/x-nu'], + 'numbers' => ['application/vnd.apple.numbers', 'application/x-iwork-numbers-sffnumbers'], + 'nzb' => ['application/x-nzb'], + 'o' => ['application/x-object'], + 'oa2' => ['application/vnd.fujitsu.oasys2'], + 'oa3' => ['application/vnd.fujitsu.oasys3'], + 'oas' => ['application/vnd.fujitsu.oasys'], + 'obd' => ['application/x-msbinder'], + 'obgx' => ['application/vnd.openblox.game+xml'], + 'obj' => ['application/x-tgif', 'model/obj'], + 'ocl' => ['text/x-ocl'], + 'oda' => ['application/oda'], + 'odb' => ['application/vnd.oasis.opendocument.database', 'application/vnd.sun.xml.base'], + 'odc' => ['application/vnd.oasis.opendocument.chart'], + 'odf' => ['application/vnd.oasis.opendocument.formula'], + 'odft' => ['application/vnd.oasis.opendocument.formula-template'], + 'odg' => ['application/vnd.oasis.opendocument.graphics'], + 'odi' => ['application/vnd.oasis.opendocument.image'], + 'odm' => ['application/vnd.oasis.opendocument.text-master'], + 'odp' => ['application/vnd.oasis.opendocument.presentation'], + 'ods' => ['application/vnd.oasis.opendocument.spreadsheet'], + 'odt' => ['application/vnd.oasis.opendocument.text'], + 'oga' => ['audio/ogg', 'audio/vorbis', 'audio/x-flac+ogg', 'audio/x-ogg', 'audio/x-oggflac', 'audio/x-speex+ogg', 'audio/x-vorbis', 'audio/x-vorbis+ogg'], + 'ogex' => ['model/vnd.opengex'], + 'ogg' => ['audio/ogg', 'audio/vorbis', 'audio/x-flac+ogg', 'audio/x-ogg', 'audio/x-oggflac', 'audio/x-speex+ogg', 'audio/x-vorbis', 'audio/x-vorbis+ogg', 'video/ogg', 'video/x-ogg', 'video/x-theora', 'video/x-theora+ogg'], + 'ogm' => ['video/x-ogm', 'video/x-ogm+ogg'], + 'ogv' => ['video/ogg', 'video/x-ogg'], + 'ogx' => ['application/ogg', 'application/x-ogg'], + 'old' => ['application/x-trash'], + 'oleo' => ['application/x-oleo'], + 'omdoc' => ['application/omdoc+xml'], + 'onepkg' => ['application/onenote'], + 'onetmp' => ['application/onenote'], + 'onetoc' => ['application/onenote'], + 'onetoc2' => ['application/onenote'], + 'ooc' => ['text/x-ooc'], + 'openvpn' => ['application/x-openvpn-profile'], + 'opf' => ['application/oebps-package+xml'], + 'opml' => ['text/x-opml', 'text/x-opml+xml'], + 'oprc' => ['application/vnd.palm', 'application/x-palm-database'], + 'opus' => ['audio/ogg', 'audio/x-ogg', 'audio/x-opus+ogg'], + 'ora' => ['image/openraster'], + 'orf' => ['image/x-olympus-orf'], + 'org' => ['application/vnd.lotus-organizer', 'text/org', 'text/x-org'], + 'osf' => ['application/vnd.yamaha.openscoreformat'], + 'osfpvg' => ['application/vnd.yamaha.openscoreformat.osfpvg+xml'], + 'osm' => ['application/vnd.openstreetmap.data+xml'], + 'otc' => ['application/vnd.oasis.opendocument.chart-template'], + 'otf' => ['application/vnd.oasis.opendocument.formula-template', 'application/x-font-otf', 'font/otf'], + 'otg' => ['application/vnd.oasis.opendocument.graphics-template'], + 'oth' => ['application/vnd.oasis.opendocument.text-web'], + 'oti' => ['application/vnd.oasis.opendocument.image-template'], + 'otp' => ['application/vnd.oasis.opendocument.presentation-template'], + 'ots' => ['application/vnd.oasis.opendocument.spreadsheet-template'], + 'ott' => ['application/vnd.oasis.opendocument.text-template'], + 'ova' => ['application/ovf', 'application/x-virtualbox-ova'], + 'ovf' => ['application/x-virtualbox-ovf'], + 'ovpn' => ['application/x-openvpn-profile'], + 'owl' => ['application/rdf+xml', 'text/rdf'], + 'owx' => ['application/owl+xml'], + 'oxps' => ['application/oxps'], + 'oxt' => ['application/vnd.openofficeorg.extension'], + 'p' => ['text/x-pascal'], + 'p10' => ['application/pkcs10'], + 'p12' => ['application/pkcs12', 'application/x-pkcs12'], + 'p65' => ['application/x-pagemaker'], + 'p7b' => ['application/x-pkcs7-certificates'], + 'p7c' => ['application/pkcs7-mime'], + 'p7m' => ['application/pkcs7-mime'], + 'p7r' => ['application/x-pkcs7-certreqresp'], + 'p7s' => ['application/pkcs7-signature'], + 'p8' => ['application/pkcs8'], + 'p8e' => ['application/pkcs8-encrypted'], + 'pac' => ['application/x-ns-proxy-autoconfig'], + 'pack' => ['application/x-java-pack200'], + 'pages' => ['application/vnd.apple.pages', 'application/x-iwork-pages-sffpages'], + 'pak' => ['application/x-pak'], + 'par2' => ['application/x-par2'], + 'part' => ['application/x-partial-download'], + 'pas' => ['text/x-pascal'], + 'pat' => ['image/x-gimp-pat'], + 'patch' => ['text/x-diff', 'text/x-patch'], + 'path' => ['text/x-systemd-unit'], + 'paw' => ['application/vnd.pawaafile'], + 'pbd' => ['application/vnd.powerbuilder6'], + 'pbm' => ['image/x-portable-bitmap'], + 'pcap' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'], + 'pcd' => ['image/x-photo-cd'], + 'pce' => ['application/x-pc-engine-rom'], + 'pcf' => ['application/x-cisco-vpn-settings', 'application/x-font-pcf'], + 'pcf.Z' => ['application/x-font-pcf'], + 'pcf.gz' => ['application/x-font-pcf'], + 'pcl' => ['application/vnd.hp-pcl'], + 'pclxl' => ['application/vnd.hp-pclxl'], + 'pct' => ['image/x-pict'], + 'pcurl' => ['application/vnd.curl.pcurl'], + 'pcx' => ['image/vnd.zbrush.pcx', 'image/x-pcx'], + 'pdb' => ['application/vnd.palm', 'application/x-aportisdoc', 'application/x-ms-pdb', 'application/x-palm-database', 'application/x-pilot'], + 'pdc' => ['application/x-aportisdoc'], + 'pde' => ['text/x-processing'], + 'pdf' => ['application/pdf', 'application/acrobat', 'application/nappdf', 'application/x-pdf', 'image/pdf'], + 'pdf.bz2' => ['application/x-bzpdf'], + 'pdf.gz' => ['application/x-gzpdf'], + 'pdf.lz' => ['application/x-lzpdf'], + 'pdf.xz' => ['application/x-xzpdf'], + 'pef' => ['image/x-pentax-pef'], + 'pem' => ['application/x-x509-ca-cert'], + 'perl' => ['application/x-perl', 'text/x-perl'], + 'pfa' => ['application/x-font-type1'], + 'pfb' => ['application/x-font-type1'], + 'pfm' => ['application/x-font-type1'], + 'pfr' => ['application/font-tdpfr', 'application/vnd.truedoc'], + 'pfx' => ['application/pkcs12', 'application/x-pkcs12'], + 'pgm' => ['image/x-portable-graymap'], + 'pgn' => ['application/vnd.chess-pgn', 'application/x-chess-pgn'], + 'pgp' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature'], + 'php' => ['application/x-php', 'application/x-httpd-php'], + 'php3' => ['application/x-php'], + 'php4' => ['application/x-php'], + 'php5' => ['application/x-php'], + 'phps' => ['application/x-php'], + 'pic' => ['image/x-pict'], + 'pict' => ['image/x-pict'], + 'pict1' => ['image/x-pict'], + 'pict2' => ['image/x-pict'], + 'pk' => ['application/x-tex-pk'], + 'pkg' => ['application/x-xar'], + 'pki' => ['application/pkixcmp'], + 'pkipath' => ['application/pkix-pkipath'], + 'pkpass' => ['application/vnd.apple.pkpass'], + 'pkr' => ['application/pgp-keys'], + 'pl' => ['application/x-perl', 'text/x-perl'], + 'pla' => ['audio/x-iriver-pla'], + 'plb' => ['application/vnd.3gpp.pic-bw-large'], + 'plc' => ['application/vnd.mobius.plc'], + 'plf' => ['application/vnd.pocketlearn'], + 'pln' => ['application/x-planperfect'], + 'pls' => ['application/pls', 'application/pls+xml', 'audio/scpls', 'audio/x-scpls'], + 'pm' => ['application/x-pagemaker', 'application/x-perl', 'text/x-perl'], + 'pm6' => ['application/x-pagemaker'], + 'pmd' => ['application/x-pagemaker'], + 'pml' => ['application/vnd.ctc-posml'], + 'png' => ['image/png', 'image/apng', 'image/vnd.mozilla.apng'], + 'pnm' => ['image/x-portable-anymap'], + 'pntg' => ['image/x-macpaint'], + 'po' => ['application/x-gettext', 'text/x-gettext-translation', 'text/x-po'], + 'pod' => ['application/x-perl', 'text/x-perl'], + 'por' => ['application/x-spss-por'], + 'portpkg' => ['application/vnd.macports.portpkg'], + 'pot' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint', 'text/x-gettext-translation-template', 'text/x-pot'], + 'potm' => ['application/vnd.ms-powerpoint.template.macroenabled.12'], + 'potx' => ['application/vnd.openxmlformats-officedocument.presentationml.template'], + 'ppam' => ['application/vnd.ms-powerpoint.addin.macroenabled.12'], + 'ppd' => ['application/vnd.cups-ppd'], + 'ppm' => ['image/x-portable-pixmap'], + 'pps' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint'], + 'ppsm' => ['application/vnd.ms-powerpoint.slideshow.macroenabled.12'], + 'ppsx' => ['application/vnd.openxmlformats-officedocument.presentationml.slideshow'], + 'ppt' => ['application/vnd.ms-powerpoint', 'application/mspowerpoint', 'application/powerpoint', 'application/x-mspowerpoint'], + 'pptm' => ['application/vnd.ms-powerpoint.presentation.macroenabled.12'], + 'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'], + 'ppz' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint'], + 'pqa' => ['application/vnd.palm', 'application/x-palm-database'], + 'prc' => ['application/vnd.palm', 'application/x-mobipocket-ebook', 'application/x-palm-database', 'application/x-pilot'], + 'pre' => ['application/vnd.lotus-freelance'], + 'prf' => ['application/pics-rules'], + 'provx' => ['application/provenance+xml'], + 'ps' => ['application/postscript'], + 'ps.bz2' => ['application/x-bzpostscript'], + 'ps.gz' => ['application/x-gzpostscript'], + 'psb' => ['application/vnd.3gpp.pic-bw-small'], + 'psd' => ['application/photoshop', 'application/x-photoshop', 'image/photoshop', 'image/psd', 'image/vnd.adobe.photoshop', 'image/x-photoshop', 'image/x-psd'], + 'psf' => ['application/x-font-linux-psf', 'audio/x-psf'], + 'psf.gz' => ['application/x-gz-font-linux-psf'], + 'psflib' => ['audio/x-psflib'], + 'psid' => ['audio/prs.sid'], + 'pskcxml' => ['application/pskc+xml'], + 'psw' => ['application/x-pocket-word'], + 'pti' => ['image/prs.pti'], + 'ptid' => ['application/vnd.pvi.ptid1'], + 'pub' => ['application/vnd.ms-publisher', 'application/x-mspublisher'], + 'pvb' => ['application/vnd.3gpp.pic-bw-var'], + 'pw' => ['application/x-pw'], + 'pwn' => ['application/vnd.3m.post-it-notes'], + 'py' => ['text/x-python', 'text/x-python3'], + 'py3' => ['text/x-python3'], + 'py3x' => ['text/x-python3'], + 'pya' => ['audio/vnd.ms-playready.media.pya'], + 'pyc' => ['application/x-python-bytecode'], + 'pyi' => ['text/x-python3'], + 'pyo' => ['application/x-python-bytecode'], + 'pys' => ['application/x-pyspread-bz-spreadsheet'], + 'pysu' => ['application/x-pyspread-spreadsheet'], + 'pyv' => ['video/vnd.ms-playready.media.pyv'], + 'pyx' => ['text/x-python'], + 'qam' => ['application/vnd.epson.quickanime'], + 'qbo' => ['application/vnd.intu.qbo'], + 'qcow' => ['application/x-qemu-disk'], + 'qcow2' => ['application/x-qemu-disk'], + 'qd' => ['application/x-fd-file', 'application/x-raw-floppy-disk-image'], + 'qed' => ['application/x-qed-disk'], + 'qfx' => ['application/vnd.intu.qfx'], + 'qif' => ['application/x-qw', 'image/x-quicktime'], + 'qml' => ['text/x-qml'], + 'qmlproject' => ['text/x-qml'], + 'qmltypes' => ['text/x-qml'], + 'qoi' => ['image/qoi'], + 'qp' => ['application/x-qpress'], + 'qps' => ['application/vnd.publishare-delta-tree'], + 'qs' => ['application/sparql-query'], + 'qt' => ['video/quicktime'], + 'qti' => ['application/x-qtiplot'], + 'qti.gz' => ['application/x-qtiplot'], + 'qtif' => ['image/x-quicktime'], + 'qtl' => ['application/x-quicktime-media-link', 'application/x-quicktimeplayer'], + 'qtvr' => ['video/quicktime'], + 'qwd' => ['application/vnd.quark.quarkxpress'], + 'qwt' => ['application/vnd.quark.quarkxpress'], + 'qxb' => ['application/vnd.quark.quarkxpress'], + 'qxd' => ['application/vnd.quark.quarkxpress'], + 'qxl' => ['application/vnd.quark.quarkxpress'], + 'qxt' => ['application/vnd.quark.quarkxpress'], + 'ra' => ['audio/vnd.m-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio', 'audio/x-realaudio'], + 'raf' => ['image/x-fuji-raf'], + 'ram' => ['application/ram', 'audio/x-pn-realaudio'], + 'raml' => ['application/raml+yaml'], + 'rapd' => ['application/route-apd+xml'], + 'rar' => ['application/x-rar-compressed', 'application/vnd.rar', 'application/x-rar'], + 'ras' => ['image/x-cmu-raster'], + 'raw' => ['image/x-panasonic-raw', 'image/x-panasonic-rw'], + 'raw-disk-image' => ['application/vnd.efi.img', 'application/x-raw-disk-image'], + 'raw-disk-image.xz' => ['application/x-raw-disk-image-xz-compressed'], + 'rax' => ['audio/vnd.m-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio'], + 'rb' => ['application/x-ruby'], + 'rcprofile' => ['application/vnd.ipunplugged.rcprofile'], + 'rdf' => ['application/rdf+xml', 'text/rdf'], + 'rdfs' => ['application/rdf+xml', 'text/rdf'], + 'rdz' => ['application/vnd.data-vision.rdz'], + 'reg' => ['text/x-ms-regedit'], + 'rej' => ['application/x-reject', 'text/x-reject'], + 'relo' => ['application/p2p-overlay+xml'], + 'rep' => ['application/vnd.businessobjects'], + 'res' => ['application/x-dtbresource+xml', 'application/x-godot-resource'], + 'rgb' => ['image/x-rgb'], + 'rif' => ['application/reginfo+xml'], + 'rip' => ['audio/vnd.rip'], + 'ris' => ['application/x-research-info-systems'], + 'rl' => ['application/resource-lists+xml'], + 'rlc' => ['image/vnd.fujixerox.edmics-rlc'], + 'rld' => ['application/resource-lists-diff+xml'], + 'rle' => ['image/rle'], + 'rm' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmi' => ['audio/midi'], + 'rmj' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmm' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmp' => ['audio/x-pn-realaudio-plugin'], + 'rms' => ['application/vnd.jcp.javame.midlet-rms', 'application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmvb' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rmx' => ['application/vnd.rn-realmedia', 'application/vnd.rn-realmedia-vbr'], + 'rnc' => ['application/relax-ng-compact-syntax', 'application/x-rnc'], + 'rng' => ['application/xml', 'text/xml'], + 'roa' => ['application/rpki-roa'], + 'roff' => ['application/x-troff', 'text/troff', 'text/x-troff'], + 'ros' => ['text/x-common-lisp'], + 'rp' => ['image/vnd.rn-realpix'], + 'rp9' => ['application/vnd.cloanto.rp9'], + 'rpm' => ['application/x-redhat-package-manager', 'application/x-rpm'], + 'rpss' => ['application/vnd.nokia.radio-presets'], + 'rpst' => ['application/vnd.nokia.radio-preset'], + 'rq' => ['application/sparql-query'], + 'rs' => ['application/rls-services+xml', 'text/rust'], + 'rsat' => ['application/atsc-rsat+xml'], + 'rsd' => ['application/rsd+xml'], + 'rsheet' => ['application/urc-ressheet+xml'], + 'rss' => ['application/rss+xml', 'text/rss'], + 'rst' => ['text/x-rst'], + 'rt' => ['text/vnd.rn-realtext'], + 'rtf' => ['application/rtf', 'text/rtf'], + 'rtx' => ['text/richtext'], + 'run' => ['application/x-makeself'], + 'rusd' => ['application/route-usd+xml'], + 'rv' => ['video/vnd.rn-realvideo', 'video/x-real-video'], + 'rvx' => ['video/vnd.rn-realvideo', 'video/x-real-video'], + 'rw2' => ['image/x-panasonic-raw2', 'image/x-panasonic-rw2'], + 's' => ['text/x-asm'], + 's3m' => ['audio/s3m', 'audio/x-s3m'], + 'saf' => ['application/vnd.yamaha.smaf-audio'], + 'sage' => ['text/x-sagemath'], + 'sam' => ['application/x-amipro'], + 'sami' => ['application/x-sami'], + 'sap' => ['application/x-sap-file', 'application/x-thomson-sap-image'], + 'sass' => ['text/x-sass'], + 'sav' => ['application/x-spss-sav', 'application/x-spss-savefile'], + 'sbml' => ['application/sbml+xml'], + 'sc' => ['application/vnd.ibm.secure-container', 'text/x-scala'], + 'scala' => ['text/x-scala'], + 'scd' => ['application/x-msschedule'], + 'scm' => ['application/vnd.lotus-screencam', 'text/x-scheme'], + 'scn' => ['application/x-godot-scene'], + 'scope' => ['text/x-systemd-unit'], + 'scq' => ['application/scvp-cv-request'], + 'scs' => ['application/scvp-cv-response'], + 'scss' => ['text/x-scss'], + 'scurl' => ['text/vnd.curl.scurl'], + 'sda' => ['application/vnd.stardivision.draw'], + 'sdc' => ['application/vnd.stardivision.calc'], + 'sdd' => ['application/vnd.stardivision.impress'], + 'sdkd' => ['application/vnd.solent.sdkm+xml'], + 'sdkm' => ['application/vnd.solent.sdkm+xml'], + 'sdp' => ['application/sdp', 'application/vnd.sdp', 'application/vnd.stardivision.impress', 'application/x-sdp'], + 'sds' => ['application/vnd.stardivision.chart'], + 'sdw' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'], + 'sea' => ['application/x-sea'], + 'see' => ['application/vnd.seemail'], + 'seed' => ['application/vnd.fdsn.seed'], + 'sema' => ['application/vnd.sema'], + 'semd' => ['application/vnd.semd'], + 'semf' => ['application/vnd.semf'], + 'senmlx' => ['application/senml+xml'], + 'sensmlx' => ['application/sensml+xml'], + 'ser' => ['application/java-serialized-object'], + 'service' => ['text/x-dbus-service', 'text/x-systemd-unit'], + 'setpay' => ['application/set-payment-initiation'], + 'setreg' => ['application/set-registration-initiation'], + 'sfc' => ['application/vnd.nintendo.snes.rom', 'application/x-snes-rom'], + 'sfd-hdstx' => ['application/vnd.hydrostatix.sof-data'], + 'sfs' => ['application/vnd.spotfire.sfs'], + 'sfv' => ['text/x-sfv'], + 'sg' => ['application/x-sg1000-rom'], + 'sgb' => ['application/x-gameboy-rom'], + 'sgd' => ['application/x-genesis-rom'], + 'sgf' => ['application/x-go-sgf'], + 'sgi' => ['image/sgi', 'image/x-sgi'], + 'sgl' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'], + 'sgm' => ['text/sgml'], + 'sgml' => ['text/sgml'], + 'sh' => ['application/x-sh', 'application/x-shellscript', 'text/x-sh'], + 'shape' => ['application/x-dia-shape'], + 'shar' => ['application/x-shar'], + 'shex' => ['text/shex'], + 'shf' => ['application/shf+xml'], + 'shn' => ['application/x-shorten', 'audio/x-shorten'], + 'shtml' => ['text/html'], + 'siag' => ['application/x-siag'], + 'sid' => ['audio/prs.sid', 'image/x-mrsid-image'], + 'sieve' => ['application/sieve'], + 'sig' => ['application/pgp-signature'], + 'sik' => ['application/x-trash'], + 'sil' => ['audio/silk'], + 'silo' => ['model/mesh'], + 'sis' => ['application/vnd.symbian.install'], + 'sisx' => ['application/vnd.symbian.install', 'x-epoc/x-sisx-app'], + 'sit' => ['application/x-stuffit', 'application/stuffit', 'application/x-sit'], + 'sitx' => ['application/x-sitx', 'application/x-stuffitx'], + 'siv' => ['application/sieve'], + 'sk' => ['image/x-skencil'], + 'sk1' => ['image/x-skencil'], + 'skd' => ['application/vnd.koan'], + 'skm' => ['application/vnd.koan'], + 'skp' => ['application/vnd.koan'], + 'skr' => ['application/pgp-keys'], + 'skt' => ['application/vnd.koan'], + 'sldm' => ['application/vnd.ms-powerpoint.slide.macroenabled.12'], + 'sldx' => ['application/vnd.openxmlformats-officedocument.presentationml.slide'], + 'slice' => ['text/x-systemd-unit'], + 'slim' => ['text/slim'], + 'slk' => ['text/spreadsheet'], + 'slm' => ['text/slim'], + 'sls' => ['application/route-s-tsid+xml'], + 'slt' => ['application/vnd.epson.salt'], + 'sm' => ['application/vnd.stepmania.stepchart'], + 'smaf' => ['application/vnd.smaf', 'application/x-smaf'], + 'smc' => ['application/vnd.nintendo.snes.rom', 'application/x-snes-rom'], + 'smd' => ['application/vnd.stardivision.mail', 'application/x-genesis-rom'], + 'smf' => ['application/vnd.stardivision.math'], + 'smi' => ['application/smil', 'application/smil+xml', 'application/x-sami'], + 'smil' => ['application/smil', 'application/smil+xml'], + 'smk' => ['video/vnd.radgamettools.smacker'], + 'sml' => ['application/smil', 'application/smil+xml'], + 'sms' => ['application/x-sms-rom'], + 'smv' => ['video/x-smv'], + 'smzip' => ['application/vnd.stepmania.package'], + 'snap' => ['application/vnd.snap'], + 'snd' => ['audio/basic'], + 'snf' => ['application/x-font-snf'], + 'so' => ['application/x-sharedlib'], + 'socket' => ['text/x-systemd-unit'], + 'spc' => ['application/x-pkcs7-certificates'], + 'spd' => ['application/x-font-speedo'], + 'spdx' => ['text/spdx'], + 'spec' => ['text/x-rpm-spec'], + 'spf' => ['application/vnd.yamaha.smaf-phrase'], + 'spl' => ['application/futuresplash', 'application/vnd.adobe.flash.movie', 'application/x-futuresplash', 'application/x-shockwave-flash'], + 'spm' => ['application/x-source-rpm'], + 'spot' => ['text/vnd.in3d.spot'], + 'spp' => ['application/scvp-vp-response'], + 'spq' => ['application/scvp-vp-request'], + 'spx' => ['application/x-apple-systemprofiler+xml', 'audio/ogg', 'audio/x-speex', 'audio/x-speex+ogg'], + 'sql' => ['application/sql', 'application/x-sql', 'text/x-sql'], + 'sqlite2' => ['application/x-sqlite2'], + 'sqlite3' => ['application/vnd.sqlite3', 'application/x-sqlite3'], + 'sqsh' => ['application/vnd.squashfs'], + 'sr2' => ['image/x-sony-sr2'], + 'src' => ['application/x-wais-source'], + 'src.rpm' => ['application/x-source-rpm'], + 'srf' => ['image/x-sony-srf'], + 'srt' => ['application/x-srt', 'application/x-subrip'], + 'sru' => ['application/sru+xml'], + 'srx' => ['application/sparql-results+xml'], + 'ss' => ['text/x-scheme'], + 'ssa' => ['text/x-ssa'], + 'ssdl' => ['application/ssdl+xml'], + 'sse' => ['application/vnd.kodak-descriptor'], + 'ssf' => ['application/vnd.epson.ssf'], + 'ssml' => ['application/ssml+xml'], + 'st' => ['application/vnd.sailingtracker.track'], + 'stc' => ['application/vnd.sun.xml.calc.template'], + 'std' => ['application/vnd.sun.xml.draw.template'], + 'stf' => ['application/vnd.wt.stf'], + 'sti' => ['application/vnd.sun.xml.impress.template'], + 'stk' => ['application/hyperstudio'], + 'stl' => ['application/vnd.ms-pki.stl', 'model/stl', 'model/x.stl-ascii', 'model/x.stl-binary'], + 'stm' => ['audio/x-stm'], + 'stpx' => ['model/step+xml'], + 'stpxz' => ['model/step-xml+zip'], + 'stpz' => ['model/step+zip'], + 'str' => ['application/vnd.pg.format'], + 'stw' => ['application/vnd.sun.xml.writer.template'], + 'sty' => ['application/x-tex', 'text/x-tex'], + 'styl' => ['text/stylus'], + 'stylus' => ['text/stylus'], + 'sub' => ['image/vnd.dvb.subtitle', 'text/vnd.dvb.subtitle', 'text/x-microdvd', 'text/x-mpsub', 'text/x-subviewer'], + 'sun' => ['image/x-sun-raster'], + 'sus' => ['application/vnd.sus-calendar'], + 'susp' => ['application/vnd.sus-calendar'], + 'sv' => ['text/x-svsrc'], + 'sv4cpio' => ['application/x-sv4cpio'], + 'sv4crc' => ['application/x-sv4crc'], + 'svc' => ['application/vnd.dvb.service'], + 'svd' => ['application/vnd.svd'], + 'svg' => ['image/svg+xml', 'image/svg'], + 'svg.gz' => ['image/svg+xml-compressed'], + 'svgz' => ['image/svg+xml', 'image/svg+xml-compressed'], + 'svh' => ['text/x-svhdr'], + 'swa' => ['application/x-director'], + 'swap' => ['text/x-systemd-unit'], + 'swf' => ['application/futuresplash', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash'], + 'swi' => ['application/vnd.aristanetworks.swi'], + 'swidtag' => ['application/swid+xml'], + 'swm' => ['application/x-ms-wim'], + 'sxc' => ['application/vnd.sun.xml.calc'], + 'sxd' => ['application/vnd.sun.xml.draw'], + 'sxg' => ['application/vnd.sun.xml.writer.global'], + 'sxi' => ['application/vnd.sun.xml.impress'], + 'sxm' => ['application/vnd.sun.xml.math'], + 'sxw' => ['application/vnd.sun.xml.writer'], + 'sylk' => ['text/spreadsheet'], + 't' => ['application/x-perl', 'application/x-troff', 'text/troff', 'text/x-perl', 'text/x-troff'], + 't2t' => ['text/x-txt2tags'], + 't3' => ['application/x-t3vm-image'], + 't38' => ['image/t38'], + 'taglet' => ['application/vnd.mynfc'], + 'tak' => ['audio/x-tak'], + 'tao' => ['application/vnd.tao.intent-module-archive'], + 'tap' => ['image/vnd.tencent.tap'], + 'tar' => ['application/x-tar', 'application/x-gtar'], + 'tar.Z' => ['application/x-tarz'], + 'tar.bz' => ['application/x-bzip-compressed-tar'], + 'tar.bz2' => ['application/x-bzip2-compressed-tar'], + 'tar.bz3' => ['application/x-bzip3-compressed-tar'], + 'tar.gz' => ['application/x-compressed-tar'], + 'tar.lrz' => ['application/x-lrzip-compressed-tar'], + 'tar.lz' => ['application/x-lzip-compressed-tar'], + 'tar.lz4' => ['application/x-lz4-compressed-tar'], + 'tar.lzma' => ['application/x-lzma-compressed-tar'], + 'tar.lzo' => ['application/x-tzo'], + 'tar.xz' => ['application/x-xz-compressed-tar'], + 'tar.zst' => ['application/x-zstd-compressed-tar'], + 'target' => ['text/x-systemd-unit'], + 'taz' => ['application/x-tarz'], + 'tb2' => ['application/x-bzip2-compressed-tar', 'application/x-bzip-compressed-tar'], + 'tbz' => ['application/x-bzip-compressed-tar'], + 'tbz2' => ['application/x-bzip2-compressed-tar', 'application/x-bzip-compressed-tar'], + 'tbz3' => ['application/x-bzip3-compressed-tar'], + 'tcap' => ['application/vnd.3gpp2.tcap'], + 'tcl' => ['application/x-tcl', 'text/tcl', 'text/x-tcl'], + 'td' => ['application/urc-targetdesc+xml'], + 'teacher' => ['application/vnd.smart.teacher'], + 'tei' => ['application/tei+xml'], + 'teicorpus' => ['application/tei+xml'], + 'tex' => ['application/x-tex', 'text/x-tex'], + 'texi' => ['application/x-texinfo', 'text/x-texinfo'], + 'texinfo' => ['application/x-texinfo', 'text/x-texinfo'], + 'text' => ['text/plain'], + 'tfi' => ['application/thraud+xml'], + 'tfm' => ['application/x-tex-tfm'], + 'tfx' => ['image/tiff-fx'], + 'tga' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'tgz' => ['application/x-compressed-tar'], + 'theme' => ['application/x-theme'], + 'themepack' => ['application/x-windows-themepack'], + 'thmx' => ['application/vnd.ms-officetheme'], + 'tif' => ['image/tiff'], + 'tiff' => ['image/tiff'], + 'timer' => ['text/x-systemd-unit'], + 'tk' => ['application/x-tcl', 'text/tcl', 'text/x-tcl'], + 'tlrz' => ['application/x-lrzip-compressed-tar'], + 'tlz' => ['application/x-lzma-compressed-tar'], + 'tmo' => ['application/vnd.tmobile-livetv'], + 'tmx' => ['application/x-tiled-tmx'], + 'tnef' => ['application/ms-tnef', 'application/vnd.ms-tnef'], + 'tnf' => ['application/ms-tnef', 'application/vnd.ms-tnef'], + 'toc' => ['application/x-cdrdao-toc'], + 'toml' => ['application/toml'], + 'torrent' => ['application/x-bittorrent'], + 'tpic' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'tpl' => ['application/vnd.groove-tool-template'], + 'tpt' => ['application/vnd.trid.tpt'], + 'tr' => ['application/x-troff', 'text/troff', 'text/x-troff'], + 'tra' => ['application/vnd.trueapp'], + 'tres' => ['application/x-godot-resource'], + 'trig' => ['application/trig', 'application/x-trig'], + 'trm' => ['application/x-msterminal'], + 'ts' => ['application/x-linguist', 'text/vnd.qt.linguist', 'text/vnd.trolltech.linguist', 'video/mp2t'], + 'tscn' => ['application/x-godot-scene'], + 'tsd' => ['application/timestamped-data'], + 'tsv' => ['text/tab-separated-values'], + 'tsx' => ['application/x-tiled-tsx'], + 'tta' => ['audio/tta', 'audio/x-tta'], + 'ttc' => ['font/collection'], + 'ttf' => ['application/x-font-truetype', 'application/x-font-ttf', 'font/ttf'], + 'ttl' => ['text/turtle'], + 'ttml' => ['application/ttml+xml'], + 'ttx' => ['application/x-font-ttx'], + 'twd' => ['application/vnd.simtech-mindmapper'], + 'twds' => ['application/vnd.simtech-mindmapper'], + 'twig' => ['text/x-twig'], + 'txd' => ['application/vnd.genomatix.tuxedo'], + 'txf' => ['application/vnd.mobius.txf'], + 'txt' => ['text/plain'], + 'txz' => ['application/x-xz-compressed-tar'], + 'typ' => ['text/x-typst'], + 'tzo' => ['application/x-tzo'], + 'tzst' => ['application/x-zstd-compressed-tar'], + 'u32' => ['application/x-authorware-bin'], + 'u8dsn' => ['message/global-delivery-status'], + 'u8hdr' => ['message/global-headers'], + 'u8mdn' => ['message/global-disposition-notification'], + 'u8msg' => ['message/global'], + 'ubj' => ['application/ubjson'], + 'udeb' => ['application/vnd.debian.binary-package', 'application/x-deb', 'application/x-debian-package'], + 'ufd' => ['application/vnd.ufdl'], + 'ufdl' => ['application/vnd.ufdl'], + 'ufraw' => ['application/x-ufraw'], + 'ui' => ['application/x-designer', 'application/x-gtk-builder'], + 'uil' => ['text/x-uil'], + 'ult' => ['audio/x-mod'], + 'ulx' => ['application/x-glulx'], + 'umj' => ['application/vnd.umajin'], + 'unf' => ['application/x-nes-rom'], + 'uni' => ['audio/x-mod'], + 'unif' => ['application/x-nes-rom'], + 'unityweb' => ['application/vnd.unity'], + 'uoml' => ['application/vnd.uoml+xml'], + 'uri' => ['text/uri-list'], + 'uris' => ['text/uri-list'], + 'url' => ['application/x-mswinurl'], + 'urls' => ['text/uri-list'], + 'usdz' => ['model/vnd.usdz+zip'], + 'ustar' => ['application/x-ustar'], + 'utz' => ['application/vnd.uiq.theme'], + 'uu' => ['text/x-uuencode'], + 'uue' => ['text/x-uuencode', 'zz-application/zz-winassoc-uu'], + 'uva' => ['audio/vnd.dece.audio'], + 'uvd' => ['application/vnd.dece.data'], + 'uvf' => ['application/vnd.dece.data'], + 'uvg' => ['image/vnd.dece.graphic'], + 'uvh' => ['video/vnd.dece.hd'], + 'uvi' => ['image/vnd.dece.graphic'], + 'uvm' => ['video/vnd.dece.mobile'], + 'uvp' => ['video/vnd.dece.pd'], + 'uvs' => ['video/vnd.dece.sd'], + 'uvt' => ['application/vnd.dece.ttml+xml'], + 'uvu' => ['video/vnd.uvvu.mp4'], + 'uvv' => ['video/vnd.dece.video'], + 'uvva' => ['audio/vnd.dece.audio'], + 'uvvd' => ['application/vnd.dece.data'], + 'uvvf' => ['application/vnd.dece.data'], + 'uvvg' => ['image/vnd.dece.graphic'], + 'uvvh' => ['video/vnd.dece.hd'], + 'uvvi' => ['image/vnd.dece.graphic'], + 'uvvm' => ['video/vnd.dece.mobile'], + 'uvvp' => ['video/vnd.dece.pd'], + 'uvvs' => ['video/vnd.dece.sd'], + 'uvvt' => ['application/vnd.dece.ttml+xml'], + 'uvvu' => ['video/vnd.uvvu.mp4'], + 'uvvv' => ['video/vnd.dece.video'], + 'uvvx' => ['application/vnd.dece.unspecified'], + 'uvvz' => ['application/vnd.dece.zip'], + 'uvx' => ['application/vnd.dece.unspecified'], + 'uvz' => ['application/vnd.dece.zip'], + 'v' => ['text/x-verilog'], + 'v64' => ['application/x-n64-rom'], + 'vala' => ['text/x-vala'], + 'vapi' => ['text/x-vala'], + 'vb' => ['application/x-virtual-boy-rom'], + 'vbox' => ['application/x-virtualbox-vbox'], + 'vbox-extpack' => ['application/x-virtualbox-vbox-extpack'], + 'vbs' => ['text/vbs', 'text/vbscript'], + 'vcard' => ['text/directory', 'text/vcard', 'text/x-vcard'], + 'vcd' => ['application/x-cdlink'], + 'vcf' => ['text/x-vcard', 'text/directory', 'text/vcard'], + 'vcg' => ['application/vnd.groove-vcard'], + 'vcs' => ['application/ics', 'text/calendar', 'text/x-vcalendar'], + 'vct' => ['text/directory', 'text/vcard', 'text/x-vcard'], + 'vcx' => ['application/vnd.vcx'], + 'vda' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'vdi' => ['application/x-vdi-disk', 'application/x-virtualbox-vdi'], + 'vds' => ['model/vnd.sap.vds'], + 'vhd' => ['application/x-vhd-disk', 'application/x-virtualbox-vhd', 'text/x-vhdl'], + 'vhdl' => ['text/x-vhdl'], + 'vhdx' => ['application/x-vhdx-disk', 'application/x-virtualbox-vhdx'], + 'vis' => ['application/vnd.visionary'], + 'viv' => ['video/vivo', 'video/vnd.vivo'], + 'vivo' => ['video/vivo', 'video/vnd.vivo'], + 'vlc' => ['application/m3u', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist', 'audio/x-mpegurl'], + 'vmdk' => ['application/x-virtualbox-vmdk', 'application/x-vmdk-disk'], + 'vob' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2', 'video/x-ms-vob'], + 'voc' => ['audio/x-voc'], + 'vor' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'], + 'vox' => ['application/x-authorware-bin'], + 'vpc' => ['application/x-vhd-disk', 'application/x-virtualbox-vhd'], + 'vrm' => ['model/vrml'], + 'vrml' => ['model/vrml'], + 'vsd' => ['application/vnd.visio'], + 'vsdm' => ['application/vnd.ms-visio.drawing.macroenabled.main+xml'], + 'vsdx' => ['application/vnd.ms-visio.drawing.main+xml'], + 'vsf' => ['application/vnd.vsf'], + 'vss' => ['application/vnd.visio'], + 'vssm' => ['application/vnd.ms-visio.stencil.macroenabled.main+xml'], + 'vssx' => ['application/vnd.ms-visio.stencil.main+xml'], + 'vst' => ['application/tga', 'application/vnd.visio', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'], + 'vstm' => ['application/vnd.ms-visio.template.macroenabled.main+xml'], + 'vstx' => ['application/vnd.ms-visio.template.main+xml'], + 'vsw' => ['application/vnd.visio'], + 'vtf' => ['image/vnd.valve.source.texture'], + 'vtt' => ['text/vtt'], + 'vtu' => ['model/vnd.vtu'], + 'vxml' => ['application/voicexml+xml'], + 'w3d' => ['application/x-director'], + 'wad' => ['application/x-doom', 'application/x-doom-wad', 'application/x-wii-wad'], + 'wadl' => ['application/vnd.sun.wadl+xml'], + 'war' => ['application/java-archive'], + 'wasm' => ['application/wasm'], + 'wav' => ['audio/wav', 'audio/vnd.wave', 'audio/wave', 'audio/x-wav'], + 'wax' => ['application/x-ms-asx', 'audio/x-ms-asx', 'audio/x-ms-wax', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'], + 'wb1' => ['application/x-quattropro'], + 'wb2' => ['application/x-quattropro'], + 'wb3' => ['application/x-quattropro'], + 'wbmp' => ['image/vnd.wap.wbmp'], + 'wbs' => ['application/vnd.criticaltools.wbs+xml'], + 'wbxml' => ['application/vnd.wap.wbxml'], + 'wcm' => ['application/vnd.ms-works'], + 'wdb' => ['application/vnd.ms-works'], + 'wdp' => ['image/jxr', 'image/vnd.ms-photo'], + 'weba' => ['audio/webm'], + 'webapp' => ['application/x-web-app-manifest+json'], + 'webm' => ['video/webm'], + 'webmanifest' => ['application/manifest+json'], + 'webp' => ['image/webp'], + 'wg' => ['application/vnd.pmi.widget'], + 'wgt' => ['application/widget'], + 'wif' => ['application/watcherinfo+xml'], + 'wim' => ['application/x-ms-wim'], + 'wk1' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + 'wk3' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + 'wk4' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + 'wkdownload' => ['application/x-partial-download'], + 'wks' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/vnd.ms-works', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'], + 'wm' => ['video/x-ms-wm'], + 'wma' => ['audio/x-ms-wma', 'audio/wma'], + 'wmd' => ['application/x-ms-wmd'], + 'wmf' => ['application/wmf', 'application/x-msmetafile', 'application/x-wmf', 'image/wmf', 'image/x-win-metafile', 'image/x-wmf'], + 'wml' => ['text/vnd.wap.wml'], + 'wmlc' => ['application/vnd.wap.wmlc'], + 'wmls' => ['text/vnd.wap.wmlscript'], + 'wmlsc' => ['application/vnd.wap.wmlscriptc'], + 'wmv' => ['audio/x-ms-wmv', 'video/x-ms-wmv'], + 'wmx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'], + 'wmz' => ['application/x-ms-wmz', 'application/x-msmetafile'], + 'woff' => ['application/font-woff', 'application/x-font-woff', 'font/woff'], + 'woff2' => ['font/woff2'], + 'wp' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wp4' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wp5' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wp6' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wpd' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wpg' => ['application/x-wpg'], + 'wpl' => ['application/vnd.ms-wpl'], + 'wpp' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'], + 'wps' => ['application/vnd.ms-works'], + 'wqd' => ['application/vnd.wqd'], + 'wri' => ['application/x-mswrite'], + 'wrl' => ['model/vrml'], + 'ws' => ['application/x-wonderswan-rom'], + 'wsc' => ['application/x-wonderswan-color-rom', 'message/vnd.wfa.wsc'], + 'wsdl' => ['application/wsdl+xml'], + 'wsgi' => ['text/x-python'], + 'wspolicy' => ['application/wspolicy+xml'], + 'wtb' => ['application/vnd.webturbo'], + 'wv' => ['audio/x-wavpack'], + 'wvc' => ['audio/x-wavpack-correction'], + 'wvp' => ['audio/x-wavpack'], + 'wvx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'], + 'wwf' => ['application/wwf', 'application/x-wwf'], + 'x32' => ['application/x-authorware-bin'], + 'x3d' => ['model/x3d+xml'], + 'x3db' => ['model/x3d+binary', 'model/x3d+fastinfoset'], + 'x3dbz' => ['model/x3d+binary'], + 'x3dv' => ['model/x3d+vrml', 'model/x3d-vrml'], + 'x3dvz' => ['model/x3d+vrml'], + 'x3dz' => ['model/x3d+xml'], + 'x3f' => ['image/x-sigma-x3f'], + 'x_b' => ['model/vnd.parasolid.transmit.binary'], + 'x_t' => ['model/vnd.parasolid.transmit.text'], + 'xac' => ['application/x-gnucash'], + 'xaml' => ['application/xaml+xml'], + 'xap' => ['application/x-silverlight-app'], + 'xar' => ['application/vnd.xara', 'application/x-xar'], + 'xav' => ['application/xcap-att+xml'], + 'xbap' => ['application/x-ms-xbap'], + 'xbd' => ['application/vnd.fujixerox.docuworks.binder'], + 'xbel' => ['application/x-xbel'], + 'xbl' => ['application/xml', 'text/xml'], + 'xbm' => ['image/x-xbitmap'], + 'xca' => ['application/xcap-caps+xml'], + 'xcf' => ['image/x-xcf'], + 'xcf.bz2' => ['image/x-compressed-xcf'], + 'xcf.gz' => ['image/x-compressed-xcf'], + 'xcs' => ['application/calendar+xml'], + 'xdf' => ['application/mrb-consumer+xml', 'application/mrb-publish+xml', 'application/xcap-diff+xml'], + 'xdgapp' => ['application/vnd.flatpak', 'application/vnd.xdgapp'], + 'xdm' => ['application/vnd.syncml.dm+xml'], + 'xdp' => ['application/vnd.adobe.xdp+xml'], + 'xdssc' => ['application/dssc+xml'], + 'xdw' => ['application/vnd.fujixerox.docuworks'], + 'xel' => ['application/xcap-el+xml'], + 'xenc' => ['application/xenc+xml'], + 'xer' => ['application/patch-ops-error+xml', 'application/xcap-error+xml'], + 'xfdf' => ['application/vnd.adobe.xfdf'], + 'xfdl' => ['application/vnd.xfdl'], + 'xhe' => ['audio/usac'], + 'xht' => ['application/xhtml+xml'], + 'xhtml' => ['application/xhtml+xml'], + 'xhvml' => ['application/xv+xml'], + 'xi' => ['audio/x-xi'], + 'xif' => ['image/vnd.xiff'], + 'xla' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlam' => ['application/vnd.ms-excel.addin.macroenabled.12'], + 'xlc' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xld' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlf' => ['application/x-xliff', 'application/x-xliff+xml', 'application/xliff+xml'], + 'xliff' => ['application/x-xliff', 'application/xliff+xml'], + 'xll' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlm' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlr' => ['application/vnd.ms-works'], + 'xls' => ['application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xlsb' => ['application/vnd.ms-excel.sheet.binary.macroenabled.12'], + 'xlsm' => ['application/vnd.ms-excel.sheet.macroenabled.12'], + 'xlsx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], + 'xlt' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xltm' => ['application/vnd.ms-excel.template.macroenabled.12'], + 'xltx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.template'], + 'xlw' => ['application/msexcel', 'application/vnd.ms-excel', 'application/x-msexcel', 'zz-application/zz-winassoc-xls'], + 'xm' => ['audio/x-xm', 'audio/xm'], + 'xmf' => ['audio/x-xmf', 'audio/xmf'], + 'xmi' => ['text/x-xmi'], + 'xml' => ['application/xml', 'text/xml'], + 'xns' => ['application/xcap-ns+xml'], + 'xo' => ['application/vnd.olpc-sugar'], + 'xop' => ['application/xop+xml'], + 'xpi' => ['application/x-xpinstall'], + 'xpl' => ['application/xproc+xml'], + 'xpm' => ['image/x-xpixmap', 'image/x-xpm'], + 'xpr' => ['application/vnd.is-xpr'], + 'xps' => ['application/vnd.ms-xpsdocument', 'application/xps'], + 'xpw' => ['application/vnd.intercon.formnet'], + 'xpx' => ['application/vnd.intercon.formnet'], + 'xsd' => ['application/xml', 'text/xml'], + 'xsl' => ['application/xml', 'application/xslt+xml'], + 'xslfo' => ['text/x-xslfo'], + 'xslt' => ['application/xslt+xml'], + 'xsm' => ['application/vnd.syncml+xml'], + 'xspf' => ['application/x-xspf+xml', 'application/xspf+xml'], + 'xul' => ['application/vnd.mozilla.xul+xml'], + 'xvm' => ['application/xv+xml'], + 'xvml' => ['application/xv+xml'], + 'xwd' => ['image/x-xwindowdump'], + 'xyz' => ['chemical/x-xyz'], + 'xz' => ['application/x-xz'], + 'yaml' => ['application/yaml', 'application/x-yaml', 'text/x-yaml', 'text/yaml'], + 'yang' => ['application/yang'], + 'yin' => ['application/yin+xml'], + 'yml' => ['application/yaml', 'application/x-yaml', 'text/x-yaml', 'text/yaml'], + 'ymp' => ['text/x-suse-ymp'], + 'yt' => ['application/vnd.youtube.yt', 'video/vnd.youtube.yt'], + 'z1' => ['application/x-zmachine'], + 'z2' => ['application/x-zmachine'], + 'z3' => ['application/x-zmachine'], + 'z4' => ['application/x-zmachine'], + 'z5' => ['application/x-zmachine'], + 'z6' => ['application/x-zmachine'], + 'z64' => ['application/x-n64-rom'], + 'z7' => ['application/x-zmachine'], + 'z8' => ['application/x-zmachine'], + 'zabw' => ['application/x-abiword'], + 'zaz' => ['application/vnd.zzazz.deck+xml'], + 'zim' => ['application/x-openzim'], + 'zip' => ['application/zip', 'application/x-zip', 'application/x-zip-compressed'], + 'zipx' => ['application/x-zip', 'application/x-zip-compressed', 'application/zip'], + 'zir' => ['application/vnd.zul'], + 'zirz' => ['application/vnd.zul'], + 'zmm' => ['application/vnd.handheld-entertainment+xml'], + 'zoo' => ['application/x-zoo'], + 'zpaq' => ['application/x-zpaq'], + 'zsav' => ['application/x-spss-sav', 'application/x-spss-savefile'], + 'zst' => ['application/zstd'], + 'zz' => ['application/zlib'], + ]; +} diff --git a/lib/symfony/mime/MimeTypesInterface.php b/lib/symfony/mime/MimeTypesInterface.php new file mode 100644 index 000000000..17d45ad21 --- /dev/null +++ b/lib/symfony/mime/MimeTypesInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +/** + * @author Fabien Potencier + */ +interface MimeTypesInterface extends MimeTypeGuesserInterface +{ + /** + * Gets the extensions for the given MIME type in decreasing order of preference. + * + * @return string[] + */ + public function getExtensions(string $mimeType): array; + + /** + * Gets the MIME types for the given extension in decreasing order of preference. + * + * @return string[] + */ + public function getMimeTypes(string $ext): array; +} diff --git a/lib/symfony/mime/Part/AbstractMultipartPart.php b/lib/symfony/mime/Part/AbstractMultipartPart.php new file mode 100644 index 000000000..1da0ddf33 --- /dev/null +++ b/lib/symfony/mime/Part/AbstractMultipartPart.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Fabien Potencier + */ +abstract class AbstractMultipartPart extends AbstractPart +{ + private ?string $boundary = null; + private array $parts = []; + + public function __construct(AbstractPart ...$parts) + { + parent::__construct(); + + foreach ($parts as $part) { + $this->parts[] = $part; + } + } + + /** + * @return AbstractPart[] + */ + public function getParts(): array + { + return $this->parts; + } + + public function getMediaType(): string + { + return 'multipart'; + } + + public function getPreparedHeaders(): Headers + { + $headers = parent::getPreparedHeaders(); + $headers->setHeaderParameter('Content-Type', 'boundary', $this->getBoundary()); + + return $headers; + } + + public function bodyToString(): string + { + $parts = $this->getParts(); + $string = ''; + foreach ($parts as $part) { + $string .= '--'.$this->getBoundary()."\r\n".$part->toString()."\r\n"; + } + $string .= '--'.$this->getBoundary()."--\r\n"; + + return $string; + } + + public function bodyToIterable(): iterable + { + $parts = $this->getParts(); + foreach ($parts as $part) { + yield '--'.$this->getBoundary()."\r\n"; + yield from $part->toIterable(); + yield "\r\n"; + } + yield '--'.$this->getBoundary()."--\r\n"; + } + + public function asDebugString(): string + { + $str = parent::asDebugString(); + foreach ($this->getParts() as $part) { + $lines = explode("\n", $part->asDebugString()); + $str .= "\n └ ".array_shift($lines); + foreach ($lines as $line) { + $str .= "\n |".$line; + } + } + + return $str; + } + + private function getBoundary(): string + { + return $this->boundary ??= strtr(base64_encode(random_bytes(6)), '+/', '-_'); + } +} diff --git a/lib/symfony/mime/Part/AbstractPart.php b/lib/symfony/mime/Part/AbstractPart.php new file mode 100644 index 000000000..130106d68 --- /dev/null +++ b/lib/symfony/mime/Part/AbstractPart.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Fabien Potencier + */ +abstract class AbstractPart +{ + private Headers $headers; + + public function __construct() + { + $this->headers = new Headers(); + } + + public function getHeaders(): Headers + { + return $this->headers; + } + + public function getPreparedHeaders(): Headers + { + $headers = clone $this->headers; + $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype()); + + return $headers; + } + + public function toString(): string + { + return $this->getPreparedHeaders()->toString()."\r\n".$this->bodyToString(); + } + + public function toIterable(): iterable + { + yield $this->getPreparedHeaders()->toString(); + yield "\r\n"; + yield from $this->bodyToIterable(); + } + + public function asDebugString(): string + { + return $this->getMediaType().'/'.$this->getMediaSubtype(); + } + + abstract public function bodyToString(): string; + + abstract public function bodyToIterable(): iterable; + + abstract public function getMediaType(): string; + + abstract public function getMediaSubtype(): string; +} diff --git a/lib/symfony/mime/Part/DataPart.php b/lib/symfony/mime/Part/DataPart.php new file mode 100644 index 000000000..f550f31fc --- /dev/null +++ b/lib/symfony/mime/Part/DataPart.php @@ -0,0 +1,168 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Fabien Potencier + */ +class DataPart extends TextPart +{ + /** @internal */ + protected array $_parent; + + private ?string $filename = null; + private string $mediaType; + private ?string $cid = null; + + /** + * @param resource|string|File $body Use a File instance to defer loading the file until rendering + */ + public function __construct($body, ?string $filename = null, ?string $contentType = null, ?string $encoding = null) + { + if ($body instanceof File && !$filename) { + $filename = $body->getFilename(); + } + + $contentType ??= $body instanceof File ? $body->getContentType() : 'application/octet-stream'; + [$this->mediaType, $subtype] = explode('/', $contentType); + + parent::__construct($body, null, $subtype, $encoding); + + if (null !== $filename) { + $this->filename = $filename; + $this->setName($filename); + } + $this->setDisposition('attachment'); + } + + public static function fromPath(string $path, ?string $name = null, ?string $contentType = null): self + { + return new self(new File($path), $name, $contentType); + } + + /** + * @return $this + */ + public function asInline(): static + { + return $this->setDisposition('inline'); + } + + /** + * @return $this + */ + public function setContentId(string $cid): static + { + if (!str_contains($cid, '@')) { + throw new InvalidArgumentException(\sprintf('Invalid cid "%s".', $cid)); + } + + $this->cid = $cid; + + return $this; + } + + public function getContentId(): string + { + return $this->cid ?: $this->cid = $this->generateContentId(); + } + + public function hasContentId(): bool + { + return null !== $this->cid; + } + + public function getMediaType(): string + { + return $this->mediaType; + } + + public function getPreparedHeaders(): Headers + { + $headers = parent::getPreparedHeaders(); + + if (null !== $this->cid) { + $headers->setHeaderBody('Id', 'Content-ID', $this->cid); + } + + if (null !== $this->filename) { + $headers->setHeaderParameter('Content-Disposition', 'filename', $this->filename); + } + + return $headers; + } + + public function asDebugString(): string + { + $str = parent::asDebugString(); + if (null !== $this->filename) { + $str .= ' filename: '.$this->filename; + } + + return $str; + } + + public function getFilename(): ?string + { + return $this->filename; + } + + public function getContentType(): string + { + return implode('/', [$this->getMediaType(), $this->getMediaSubtype()]); + } + + private function generateContentId(): string + { + return bin2hex(random_bytes(16)).'@symfony'; + } + + public function __sleep(): array + { + // converts the body to a string + parent::__sleep(); + + $this->_parent = []; + foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) { + $r = new \ReflectionProperty(TextPart::class, $name); + $this->_parent[$name] = $r->getValue($this); + } + $this->_headers = $this->getHeaders(); + + return ['_headers', '_parent', 'filename', 'mediaType']; + } + + /** + * @return void + */ + public function __wakeup() + { + $r = new \ReflectionProperty(AbstractPart::class, 'headers'); + $r->setValue($this, $this->_headers); + unset($this->_headers); + + if (!\is_array($this->_parent)) { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) { + if (null !== $this->_parent[$name] && !\is_string($this->_parent[$name]) && !$this->_parent[$name] instanceof File) { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + $r = new \ReflectionProperty(TextPart::class, $name); + $r->setValue($this, $this->_parent[$name]); + } + unset($this->_parent); + } +} diff --git a/lib/symfony/mime/Part/File.php b/lib/symfony/mime/Part/File.php new file mode 100644 index 000000000..cd05a3dee --- /dev/null +++ b/lib/symfony/mime/Part/File.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\MimeTypes; + +/** + * @author Fabien Potencier + */ +class File +{ + private static MimeTypes $mimeTypes; + + public function __construct( + private string $path, + private ?string $filename = null, + ) { + } + + public function getPath(): string + { + return $this->path; + } + + public function getContentType(): string + { + $ext = strtolower(pathinfo($this->path, \PATHINFO_EXTENSION)); + self::$mimeTypes ??= new MimeTypes(); + + return self::$mimeTypes->getMimeTypes($ext)[0] ?? 'application/octet-stream'; + } + + public function getSize(): int + { + return filesize($this->path); + } + + public function getFilename(): string + { + return $this->filename ??= basename($this->getPath()); + } +} diff --git a/lib/symfony/mime/Part/MessagePart.php b/lib/symfony/mime/Part/MessagePart.php new file mode 100644 index 000000000..9d30544ae --- /dev/null +++ b/lib/symfony/mime/Part/MessagePart.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Message; +use Symfony\Component\Mime\RawMessage; + +/** + * @final + * + * @author Fabien Potencier + */ +class MessagePart extends DataPart +{ + private RawMessage $message; + + public function __construct(RawMessage $message) + { + if ($message instanceof Message) { + $name = $message->getHeaders()->getHeaderBody('Subject').'.eml'; + } else { + $name = 'email.eml'; + } + parent::__construct('', $name); + + $this->message = $message; + } + + public function getMediaType(): string + { + return 'message'; + } + + public function getMediaSubtype(): string + { + return 'rfc822'; + } + + public function getBody(): string + { + return $this->message->toString(); + } + + public function bodyToString(): string + { + return $this->getBody(); + } + + public function bodyToIterable(): iterable + { + return $this->message->toIterable(); + } + + public function __sleep(): array + { + return ['message']; + } + + public function __wakeup(): void + { + $this->__construct($this->message); + } +} diff --git a/lib/symfony/mime/Part/Multipart/AlternativePart.php b/lib/symfony/mime/Part/Multipart/AlternativePart.php new file mode 100644 index 000000000..fd7542347 --- /dev/null +++ b/lib/symfony/mime/Part/Multipart/AlternativePart.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Part\AbstractMultipartPart; + +/** + * @author Fabien Potencier + */ +final class AlternativePart extends AbstractMultipartPart +{ + public function getMediaSubtype(): string + { + return 'alternative'; + } +} diff --git a/lib/symfony/mime/Part/Multipart/DigestPart.php b/lib/symfony/mime/Part/Multipart/DigestPart.php new file mode 100644 index 000000000..27537f15b --- /dev/null +++ b/lib/symfony/mime/Part/Multipart/DigestPart.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Part\AbstractMultipartPart; +use Symfony\Component\Mime\Part\MessagePart; + +/** + * @author Fabien Potencier + */ +final class DigestPart extends AbstractMultipartPart +{ + public function __construct(MessagePart ...$parts) + { + parent::__construct(...$parts); + } + + public function getMediaSubtype(): string + { + return 'digest'; + } +} diff --git a/lib/symfony/mime/Part/Multipart/FormDataPart.php b/lib/symfony/mime/Part/Multipart/FormDataPart.php new file mode 100644 index 000000000..4ccfd3071 --- /dev/null +++ b/lib/symfony/mime/Part/Multipart/FormDataPart.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Part\AbstractMultipartPart; +use Symfony\Component\Mime\Part\TextPart; + +/** + * Implements RFC 7578. + * + * @author Fabien Potencier + */ +final class FormDataPart extends AbstractMultipartPart +{ + private array $fields = []; + + /** + * @param array $fields + */ + public function __construct(array $fields = []) + { + parent::__construct(); + + $this->fields = $fields; + + // HTTP does not support \r\n in header values + $this->getHeaders()->setMaxLineLength(\PHP_INT_MAX); + } + + public function getMediaSubtype(): string + { + return 'form-data'; + } + + public function getParts(): array + { + return $this->prepareFields($this->fields); + } + + private function prepareFields(array $fields): array + { + $values = []; + + $prepare = function ($item, $key, $root = null) use (&$values, &$prepare) { + if (null === $root && \is_int($key) && \is_array($item)) { + if (1 !== \count($item)) { + throw new InvalidArgumentException(\sprintf('Form field values with integer keys can only have one array element, the key being the field name and the value being the field value, %d provided.', \count($item))); + } + + $key = key($item); + $item = $item[$key]; + } + + $fieldName = null !== $root ? \sprintf('%s[%s]', $root, $key) : $key; + + if (\is_array($item)) { + array_walk($item, $prepare, $fieldName); + + return; + } + + if (!\is_string($item) && !$item instanceof TextPart) { + throw new InvalidArgumentException(\sprintf('The value of the form field "%s" can only be a string, an array, or an instance of TextPart, "%s" given.', $fieldName, get_debug_type($item))); + } + + $values[] = $this->preparePart($fieldName, $item); + }; + + array_walk($fields, $prepare); + + return $values; + } + + private function preparePart(string $name, string|TextPart $value): TextPart + { + if (\is_string($value)) { + return $this->configurePart($name, new TextPart($value, 'utf-8', 'plain', '8bit')); + } + + return $this->configurePart($name, $value); + } + + private function configurePart(string $name, TextPart $part): TextPart + { + static $r; + + $r ??= new \ReflectionProperty(TextPart::class, 'encoding'); + + $part->setDisposition('form-data'); + $part->setName($name); + // HTTP does not support \r\n in header values + $part->getHeaders()->setMaxLineLength(\PHP_INT_MAX); + $r->setValue($part, '8bit'); + + return $part; + } +} diff --git a/lib/symfony/mime/Part/Multipart/MixedPart.php b/lib/symfony/mime/Part/Multipart/MixedPart.php new file mode 100644 index 000000000..c8d7028cd --- /dev/null +++ b/lib/symfony/mime/Part/Multipart/MixedPart.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Part\AbstractMultipartPart; + +/** + * @author Fabien Potencier + */ +final class MixedPart extends AbstractMultipartPart +{ + public function getMediaSubtype(): string + { + return 'mixed'; + } +} diff --git a/lib/symfony/mime/Part/Multipart/RelatedPart.php b/lib/symfony/mime/Part/Multipart/RelatedPart.php new file mode 100644 index 000000000..a0d6a1c2c --- /dev/null +++ b/lib/symfony/mime/Part/Multipart/RelatedPart.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part\Multipart; + +use Symfony\Component\Mime\Part\AbstractMultipartPart; +use Symfony\Component\Mime\Part\AbstractPart; + +/** + * @author Fabien Potencier + */ +final class RelatedPart extends AbstractMultipartPart +{ + private AbstractPart $mainPart; + + public function __construct(AbstractPart $mainPart, AbstractPart $part, AbstractPart ...$parts) + { + $this->mainPart = $mainPart; + $this->prepareParts($part, ...$parts); + + parent::__construct($part, ...$parts); + } + + public function getParts(): array + { + return array_merge([$this->mainPart], parent::getParts()); + } + + public function getMediaSubtype(): string + { + return 'related'; + } + + private function generateContentId(): string + { + return bin2hex(random_bytes(16)).'@symfony'; + } + + private function prepareParts(AbstractPart ...$parts): void + { + foreach ($parts as $part) { + if (!$part->getHeaders()->has('Content-ID')) { + $part->getHeaders()->setHeaderBody('Id', 'Content-ID', $this->generateContentId()); + } + } + } +} diff --git a/lib/symfony/mime/Part/SMimePart.php b/lib/symfony/mime/Part/SMimePart.php new file mode 100644 index 000000000..57b9766b1 --- /dev/null +++ b/lib/symfony/mime/Part/SMimePart.php @@ -0,0 +1,111 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Sebastiaan Stok + */ +class SMimePart extends AbstractPart +{ + /** @internal */ + protected Headers $_headers; + + private iterable|string $body; + private string $type; + private string $subtype; + private array $parameters; + + public function __construct(iterable|string $body, string $type, string $subtype, array $parameters) + { + parent::__construct(); + + $this->body = $body; + $this->type = $type; + $this->subtype = $subtype; + $this->parameters = $parameters; + } + + public function getMediaType(): string + { + return $this->type; + } + + public function getMediaSubtype(): string + { + return $this->subtype; + } + + public function bodyToString(): string + { + if (\is_string($this->body)) { + return $this->body; + } + + $body = ''; + foreach ($this->body as $chunk) { + $body .= $chunk; + } + $this->body = $body; + + return $body; + } + + public function bodyToIterable(): iterable + { + if (\is_string($this->body)) { + yield $this->body; + + return; + } + + $body = ''; + foreach ($this->body as $chunk) { + $body .= $chunk; + yield $chunk; + } + $this->body = $body; + } + + public function getPreparedHeaders(): Headers + { + $headers = clone parent::getHeaders(); + + $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype()); + + foreach ($this->parameters as $name => $value) { + $headers->setHeaderParameter('Content-Type', $name, $value); + } + + return $headers; + } + + public function __sleep(): array + { + // convert iterables to strings for serialization + if (is_iterable($this->body)) { + $this->body = $this->bodyToString(); + } + + $this->_headers = $this->getHeaders(); + + return ['_headers', 'body', 'type', 'subtype', 'parameters']; + } + + public function __wakeup(): void + { + $r = new \ReflectionProperty(AbstractPart::class, 'headers'); + $r->setValue($this, $this->_headers); + unset($this->_headers); + } +} diff --git a/lib/symfony/mime/Part/TextPart.php b/lib/symfony/mime/Part/TextPart.php new file mode 100644 index 000000000..30e3005ff --- /dev/null +++ b/lib/symfony/mime/Part/TextPart.php @@ -0,0 +1,248 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime\Part; + +use Symfony\Component\Mime\Encoder\Base64ContentEncoder; +use Symfony\Component\Mime\Encoder\ContentEncoderInterface; +use Symfony\Component\Mime\Encoder\EightBitContentEncoder; +use Symfony\Component\Mime\Encoder\QpContentEncoder; +use Symfony\Component\Mime\Exception\InvalidArgumentException; +use Symfony\Component\Mime\Header\Headers; + +/** + * @author Fabien Potencier + */ +class TextPart extends AbstractPart +{ + /** @internal */ + protected Headers $_headers; + + private static array $encoders = []; + + /** @var resource|string|File */ + private $body; + private ?string $charset; + private string $subtype; + private ?string $disposition = null; + private ?string $name = null; + private string $encoding; + private ?bool $seekable = null; + + /** + * @param resource|string|File $body Use a File instance to defer loading the file until rendering + */ + public function __construct($body, ?string $charset = 'utf-8', string $subtype = 'plain', ?string $encoding = null) + { + parent::__construct(); + + if (!\is_string($body) && !\is_resource($body) && !$body instanceof File) { + throw new \TypeError(\sprintf('The body of "%s" must be a string, a resource, or an instance of "%s" (got "%s").', self::class, File::class, get_debug_type($body))); + } + + if ($body instanceof File) { + $path = $body->getPath(); + if ((is_file($path) && !is_readable($path)) || is_dir($path)) { + throw new InvalidArgumentException(\sprintf('Path "%s" is not readable.', $path)); + } + } + + $this->body = $body; + $this->charset = $charset; + $this->subtype = $subtype; + $this->seekable = \is_resource($body) ? stream_get_meta_data($body)['seekable'] && 0 === fseek($body, 0, \SEEK_CUR) : null; + + if (null === $encoding) { + $this->encoding = $this->chooseEncoding(); + } else { + if ('quoted-printable' !== $encoding && 'base64' !== $encoding && '8bit' !== $encoding) { + throw new InvalidArgumentException(\sprintf('The encoding must be one of "quoted-printable", "base64", or "8bit" ("%s" given).', $encoding)); + } + $this->encoding = $encoding; + } + } + + public function getMediaType(): string + { + return 'text'; + } + + public function getMediaSubtype(): string + { + return $this->subtype; + } + + /** + * @param string $disposition one of attachment, inline, or form-data + * + * @return $this + */ + public function setDisposition(string $disposition): static + { + $this->disposition = $disposition; + + return $this; + } + + /** + * @return ?string null or one of attachment, inline, or form-data + */ + public function getDisposition(): ?string + { + return $this->disposition; + } + + /** + * Sets the name of the file (used by FormDataPart). + * + * @return $this + */ + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + /** + * Gets the name of the file. + */ + public function getName(): ?string + { + return $this->name; + } + + public function getBody(): string + { + if ($this->body instanceof File) { + if (false === $ret = @file_get_contents($this->body->getPath())) { + throw new InvalidArgumentException(error_get_last()['message']); + } + + return $ret; + } + + if (null === $this->seekable) { + return $this->body; + } + + if ($this->seekable) { + rewind($this->body); + } + + return stream_get_contents($this->body) ?: ''; + } + + public function bodyToString(): string + { + return $this->getEncoder()->encodeString($this->getBody(), $this->charset); + } + + public function bodyToIterable(): iterable + { + if ($this->body instanceof File) { + $path = $this->body->getPath(); + if (false === $handle = @fopen($path, 'r', false)) { + throw new InvalidArgumentException(\sprintf('Unable to open path "%s".', $path)); + } + + yield from $this->getEncoder()->encodeByteStream($handle); + } elseif (null !== $this->seekable) { + if ($this->seekable) { + rewind($this->body); + } + yield from $this->getEncoder()->encodeByteStream($this->body); + } else { + yield $this->getEncoder()->encodeString($this->body); + } + } + + public function getPreparedHeaders(): Headers + { + $headers = parent::getPreparedHeaders(); + + $headers->setHeaderBody('Parameterized', 'Content-Type', $this->getMediaType().'/'.$this->getMediaSubtype()); + if ($this->charset) { + $headers->setHeaderParameter('Content-Type', 'charset', $this->charset); + } + if ($this->name && 'form-data' !== $this->disposition) { + $headers->setHeaderParameter('Content-Type', 'name', $this->name); + } + $headers->setHeaderBody('Text', 'Content-Transfer-Encoding', $this->encoding); + + if (!$headers->has('Content-Disposition') && null !== $this->disposition) { + $headers->setHeaderBody('Parameterized', 'Content-Disposition', $this->disposition); + if ($this->name) { + $headers->setHeaderParameter('Content-Disposition', 'name', $this->name); + } + } + + return $headers; + } + + public function asDebugString(): string + { + $str = parent::asDebugString(); + if (null !== $this->charset) { + $str .= ' charset: '.$this->charset; + } + if (null !== $this->disposition) { + $str .= ' disposition: '.$this->disposition; + } + + return $str; + } + + private function getEncoder(): ContentEncoderInterface + { + if ('8bit' === $this->encoding) { + return self::$encoders[$this->encoding] ??= new EightBitContentEncoder(); + } + + if ('quoted-printable' === $this->encoding) { + return self::$encoders[$this->encoding] ??= new QpContentEncoder(); + } + + return self::$encoders[$this->encoding] ??= new Base64ContentEncoder(); + } + + private function chooseEncoding(): string + { + if (null === $this->charset) { + return 'base64'; + } + + return 'quoted-printable'; + } + + public function __sleep(): array + { + // convert resources to strings for serialization + if (null !== $this->seekable) { + $this->body = $this->getBody(); + $this->seekable = null; + } + + $this->_headers = $this->getHeaders(); + + return ['_headers', 'body', 'charset', 'subtype', 'disposition', 'name', 'encoding']; + } + + /** + * @return void + */ + public function __wakeup() + { + $r = new \ReflectionProperty(AbstractPart::class, 'headers'); + $r->setValue($this, $this->_headers); + unset($this->_headers); + } +} diff --git a/lib/symfony/mime/README.md b/lib/symfony/mime/README.md new file mode 100644 index 000000000..8e4d5c77f --- /dev/null +++ b/lib/symfony/mime/README.md @@ -0,0 +1,13 @@ +MIME Component +============== + +The MIME component allows manipulating MIME messages. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/mime.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/lib/symfony/mime/RawMessage.php b/lib/symfony/mime/RawMessage.php new file mode 100644 index 000000000..2b1b52cde --- /dev/null +++ b/lib/symfony/mime/RawMessage.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mime; + +use Symfony\Component\Mime\Exception\LogicException; + +/** + * @author Fabien Potencier + */ +class RawMessage +{ + /** @var iterable|string|resource */ + private $message; + private bool $isGeneratorClosed; + + /** + * @param iterable|string|resource $message + */ + public function __construct(mixed $message) + { + $this->message = $message; + } + + public function __destruct() + { + if (\is_resource($this->message)) { + fclose($this->message); + } + } + + public function toString(): string + { + if (\is_string($this->message)) { + return $this->message; + } + + if (\is_resource($this->message)) { + return stream_get_contents($this->message, -1, 0); + } + + $message = ''; + foreach ($this->message as $chunk) { + $message .= $chunk; + } + + return $this->message = $message; + } + + public function toIterable(): iterable + { + if ($this->isGeneratorClosed ?? false) { + trigger_deprecation('symfony/mime', '6.4', 'Sending an email with a closed generator is deprecated and will throw in 7.0.'); + // throw new LogicException('Unable to send the email as its generator is already closed.'); + } + + if (\is_string($this->message)) { + yield $this->message; + + return; + } + + if (\is_resource($this->message)) { + rewind($this->message); + while ($line = fgets($this->message)) { + yield $line; + } + + return; + } + + if ($this->message instanceof \Generator) { + $message = fopen('php://temp', 'w+'); + foreach ($this->message as $chunk) { + fwrite($message, $chunk); + yield $chunk; + } + $this->isGeneratorClosed = !$this->message->valid(); + $this->message = $message; + + return; + } + + foreach ($this->message as $chunk) { + yield $chunk; + } + } + + /** + * @return void + * + * @throws LogicException if the message is not valid + */ + public function ensureValidity() + { + } + + public function __serialize(): array + { + return [$this->toString()]; + } + + public function __unserialize(array $data): void + { + [$this->message] = $data; + } +} diff --git a/lib/symfony/mime/Resources/bin/update_mime_types.php b/lib/symfony/mime/Resources/bin/update_mime_types.php new file mode 100644 index 000000000..b707d458e --- /dev/null +++ b/lib/symfony/mime/Resources/bin/update_mime_types.php @@ -0,0 +1,168 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if ('cli' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + +// load new map +$data = json_decode(file_get_contents('https://cdn.jsdelivr.net/gh/jshttp/mime-db/db.json'), true); +$new = []; +foreach ($data as $mimeType => $mimeTypeInformation) { + if (!array_key_exists('extensions', $mimeTypeInformation)) { + continue; + } + $new[$mimeType] = $mimeTypeInformation['extensions']; +} + +$xml = simplexml_load_string(file_get_contents('https://gitlab.freedesktop.org/xdg/shared-mime-info/-/raw/master/data/freedesktop.org.xml.in')); +foreach ($xml as $node) { + $exts = []; + foreach ($node->glob as $glob) { + $pattern = (string) $glob['pattern']; + if ('*' != $pattern[0] || '.' != $pattern[1]) { + continue; + } + + $exts[] = substr($pattern, 2); + } + + if (!$exts) { + continue; + } + + $mt = strtolower((string) $node['type']); + $new[$mt] = array_merge($new[$mt] ?? [], $exts); + foreach ($node->alias as $alias) { + $mt = strtolower((string) $alias['type']); + $new[$mt] = array_merge($new[$mt] ?? [], $exts); + } +} + +// load current map +$data = file_get_contents($output = __DIR__.'/../../MimeTypes.php'); +$current = []; +$pre = ''; +$post = ''; +foreach (explode("\n", $data) as $line) { + if (!preg_match("{^ '([^']+/[^']+)' => \['(.+)'\],$}", $line, $matches)) { + if (!$current) { + $pre .= $line."\n"; + } else { + $post .= $line."\n"; + } + continue; + } + $current[$matches[1]] = explode("', '", $matches[2]); +} + +$data = $pre; + +// reverse map +// we prefill the extensions with some preferences for content-types +$exts = [ + 'asice' => ['application/vnd.etsi.asic-e+zip'], + 'bz2' => ['application/x-bz2'], + 'csv' => ['text/csv'], + 'ecma' => ['application/ecmascript'], + 'flv' => ['video/x-flv'], + 'gif' => ['image/gif'], + 'gz' => ['application/x-gzip'], + 'htm' => ['text/html'], + 'html' => ['text/html'], + 'jar' => ['application/x-java-archive'], + 'jpg' => ['image/jpeg'], + 'js' => ['text/javascript'], + 'keynote' => ['application/vnd.apple.keynote'], + 'key' => ['application/vnd.apple.keynote'], + 'm3u' => ['audio/x-mpegurl'], + 'm4a' => ['audio/mp4'], + 'md' => ['text/markdown', 'text/x-markdown'], + 'mdb' => ['application/x-msaccess'], + 'mid' => ['audio/midi'], + 'mov' => ['video/quicktime'], + 'mp3' => ['audio/mpeg'], + 'ogg' => ['audio/ogg'], + 'pdf' => ['application/pdf'], + 'php' => ['application/x-php'], + 'png' => ['image/png'], + 'ppt' => ['application/vnd.ms-powerpoint'], + 'rar' => ['application/x-rar-compressed'], + 'hqx' => ['application/stuffit'], + 'sit' => ['application/x-stuffit', 'application/stuffit'], + 'svg' => ['image/svg+xml'], + 'tar' => ['application/x-tar'], + 'tif' => ['image/tiff'], + 'ttf' => ['application/x-font-truetype'], + 'vcf' => ['text/x-vcard'], + 'wav' => ['audio/wav'], + 'wma' => ['audio/x-ms-wma'], + 'wmv' => ['audio/x-ms-wmv'], + 'xls' => ['application/vnd.ms-excel'], + 'yaml' => ['application/yaml'], + 'yml' => ['application/yaml'], + 'zip' => ['application/zip'], +]; + +// we merge the 2 maps (we never remove old mime types) +$map = array_replace_recursive($current, $new); + +foreach ($exts as $ext => $types) { + foreach ($types as $mt) { + if (!isset($map[$mt])) { + $map += [$mt => [$ext]]; + } + } +} +ksort($map); + +foreach ($map as $mimeType => $extensions) { + foreach ($exts as $ext => $types) { + if (in_array($mimeType, $types, true)) { + array_unshift($extensions, $ext); + } + } + $data .= sprintf(" '%s' => ['%s'],\n", $mimeType, implode("', '", array_unique($extensions))); +} +$data .= $post; + +foreach ($map as $mimeType => $extensions) { + foreach ($extensions as $extension) { + if ('application/octet-stream' === $mimeType && 'bin' !== $extension) { + continue; + } + + $exts[$extension][] = $mimeType; + } +} +ksort($exts); + +$updated = ''; +$state = 0; +foreach (explode("\n", $data) as $line) { + if (!preg_match("{^ '([^'/]+)' => \['(.+)'\],$}", $line, $matches)) { + if (1 === $state) { + $state = 2; + foreach ($exts as $ext => $mimeTypes) { + $updated .= sprintf(" '%s' => ['%s'],\n", $ext, implode("', '", array_unique($mimeTypes))); + } + } + $updated .= $line."\n"; + continue; + } + $state = 1; +} + +$updated = preg_replace('{Updated from upstream on .+?\.}', sprintf('Updated from upstream on %s.', date('Y-m-d')), $updated, -1); + +file_put_contents($output, rtrim($updated, "\n")."\n"); + +echo "Done.\n"; diff --git a/lib/symfony/mime/composer.json b/lib/symfony/mime/composer.json new file mode 100644 index 000000000..ae5ca36d8 --- /dev/null +++ b/lib/symfony/mime/composer.json @@ -0,0 +1,48 @@ +{ + "name": "symfony/mime", + "type": "library", + "description": "Allows manipulating MIME messages", + "keywords": ["mime", "mime-type"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "require-dev": { + "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": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Mime\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/lib/symfony/polyfill-intl-idn/Idn.php b/lib/symfony/polyfill-intl-idn/Idn.php index 3dc061209..448f74cef 100644 --- a/lib/symfony/polyfill-intl-idn/Idn.php +++ b/lib/symfony/polyfill-intl-idn/Idn.php @@ -145,7 +145,11 @@ final class Idn */ public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) { - if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) { + if (\PHP_VERSION_ID > 80400 && '' === $domainName) { + throw new \ValueError('idn_to_ascii(): Argument #1 ($domain) cannot be empty'); + } + + if (self::INTL_IDNA_VARIANT_2003 === $variant) { @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); } @@ -198,7 +202,11 @@ final class Idn */ public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) { - if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) { + if (\PHP_VERSION_ID > 80400 && '' === $domainName) { + throw new \ValueError('idn_to_utf8(): Argument #1 ($domain) cannot be empty'); + } + + if (self::INTL_IDNA_VARIANT_2003 === $variant) { @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); } @@ -280,10 +288,6 @@ final class Idn switch ($data['status']) { case 'disallowed': - $info->errors |= self::ERROR_DISALLOWED; - - // no break. - case 'valid': $str .= mb_chr($codePoint, 'utf-8'); @@ -294,7 +298,7 @@ final class Idn break; case 'mapped': - $str .= $data['mapping']; + $str .= $transitional && 0x1E9E === $codePoint ? 'ss' : $data['mapping']; break; @@ -346,6 +350,18 @@ final class Idn $validationOptions = $options; if ('xn--' === substr($label, 0, 4)) { + // Step 4.1. If the label contains any non-ASCII code point (i.e., a code point greater than U+007F), + // record that there was an error, and continue with the next label. + if (preg_match('/[^\x00-\x7F]/', $label)) { + $info->errors |= self::ERROR_PUNYCODE; + + continue; + } + + // Step 4.2. Attempt to convert the rest of the label to Unicode according to Punycode [RFC3492]. If + // that conversion fails, record that there was an error, and continue + // with the next label. Otherwise replace the original label in the string by the results of the + // conversion. try { $label = self::punycodeDecode(substr($label, 4)); } catch (\Exception $e) { @@ -516,6 +532,8 @@ final class Idn if ('-' === substr($label, -1, 1)) { $info->errors |= self::ERROR_TRAILING_HYPHEN; } + } elseif ('xn--' === substr($label, 0, 4)) { + $info->errors |= self::ERROR_PUNYCODE; } // Step 4. The label must not contain a U+002E (.) FULL STOP. diff --git a/lib/symfony/polyfill-intl-idn/composer.json b/lib/symfony/polyfill-intl-idn/composer.json index 78e478ee8..760debcd2 100644 --- a/lib/symfony/polyfill-intl-idn/composer.json +++ b/lib/symfony/polyfill-intl-idn/composer.json @@ -20,9 +20,8 @@ } ], "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" }, @@ -33,9 +32,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/lib/symfony/polyfill-intl-normalizer/composer.json b/lib/symfony/polyfill-intl-normalizer/composer.json index 2c4de2c83..9bd04e887 100644 --- a/lib/symfony/polyfill-intl-normalizer/composer.json +++ b/lib/symfony/polyfill-intl-normalizer/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, @@ -28,9 +28,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/lib/symfony/polyfill-mbstring/Mbstring.php b/lib/symfony/polyfill-mbstring/Mbstring.php index 2e0b96940..31e36a368 100644 --- a/lib/symfony/polyfill-mbstring/Mbstring.php +++ b/lib/symfony/polyfill-mbstring/Mbstring.php @@ -48,6 +48,11 @@ namespace Symfony\Polyfill\Mbstring; * - mb_strstr - Finds first occurrence of a string within another * - mb_strwidth - Return width of string * - mb_substr_count - Count the number of substring occurrences + * - mb_ucfirst - Make a string's first character uppercase + * - mb_lcfirst - Make a string's first character lowercase + * - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string + * - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string + * - mb_rtrim - Strip whitespace (or other characters) from the end of a string * * Not implemented: * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) @@ -80,6 +85,15 @@ final class Mbstring public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) { + if (\is_array($s)) { + $r = []; + foreach ($s as $str) { + $r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding); + } + + return $r; + } + if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) { $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); } else { @@ -410,12 +424,6 @@ final class Mbstring public static function mb_check_encoding($var = null, $encoding = null) { - if (PHP_VERSION_ID < 70200 && \is_array($var)) { - trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING); - - return null; - } - if (null === $encoding) { if (null === $var) { return false; @@ -437,7 +445,6 @@ final class Mbstring } return true; - } public static function mb_detect_encoding($str, $encodingList = null, $strict = false) @@ -827,7 +834,7 @@ final class Mbstring return $code; } - public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string { if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); @@ -835,17 +842,8 @@ final class Mbstring if (null === $encoding) { $encoding = self::mb_internal_encoding(); - } - - try { - $validEncoding = @self::mb_check_encoding('', $encoding); - } catch (\ValueError $e) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); - } - - // BC for PHP 7.3 and lower - if (!$validEncoding) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } else { + self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given'); } if (self::mb_strlen($pad_string, $encoding) <= 0) { @@ -871,6 +869,34 @@ final class Mbstring } } + public static function mb_ucfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + + public static function mb_lcfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + private static function getSubpart($pos, $part, $haystack, $encoding) { if (false === $pos) { @@ -944,4 +970,76 @@ final class Mbstring return $encoding; } + + public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given'); + } + + if ('' === $characters) { + return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding); + } + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $string)) { + $string = @iconv('UTF-8', 'UTF-8//IGNORE', $string); + } + if (null !== $characters && !preg_match('//u', $characters)) { + $characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters); + } + } else { + $string = iconv($encoding, 'UTF-8//IGNORE', $string); + + if (null !== $characters) { + $characters = iconv($encoding, 'UTF-8//IGNORE', $characters); + } + } + + if (null === $characters) { + $characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}"; + } else { + $characters = preg_quote($characters); + } + + $string = preg_replace(sprintf($regex, $characters), '', $string); + + if (null === $encoding) { + return $string; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $string); + } + + private static function assertEncoding(string $encoding, string $errorFormat): void + { + try { + $validEncoding = @self::mb_check_encoding('', $encoding); + } catch (\ValueError $e) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + + // BC for PHP 7.3 and lower + if (!$validEncoding) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + } } diff --git a/lib/symfony/polyfill-mbstring/bootstrap.php b/lib/symfony/polyfill-mbstring/bootstrap.php index ecf1a0352..ff51ae079 100644 --- a/lib/symfony/polyfill-mbstring/bootstrap.php +++ b/lib/symfony/polyfill-mbstring/bootstrap.php @@ -136,6 +136,27 @@ if (!function_exists('mb_str_pad')) { function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } } +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } +} + + if (extension_loaded('mbstring')) { return; } diff --git a/lib/symfony/polyfill-mbstring/bootstrap80.php b/lib/symfony/polyfill-mbstring/bootstrap80.php index 2f9fb5b42..5236e6dcc 100644 --- a/lib/symfony/polyfill-mbstring/bootstrap80.php +++ b/lib/symfony/polyfill-mbstring/bootstrap80.php @@ -93,7 +93,7 @@ if (!function_exists('mb_strstr')) { function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } } if (!function_exists('mb_get_info')) { - function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); } + function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); } } if (!function_exists('mb_http_output')) { function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } @@ -132,6 +132,26 @@ if (!function_exists('mb_str_pad')) { function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } } +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } +} + if (extension_loaded('mbstring')) { return; } diff --git a/lib/symfony/polyfill-mbstring/composer.json b/lib/symfony/polyfill-mbstring/composer.json index 943e50296..daa07f86b 100644 --- a/lib/symfony/polyfill-mbstring/composer.json +++ b/lib/symfony/polyfill-mbstring/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2", + "ext-iconv": "*" }, "provide": { "ext-mbstring": "*" @@ -30,9 +31,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/lib/symfony/polyfill-php72/Php72.php b/lib/symfony/polyfill-php72/Php72.php deleted file mode 100644 index 7bf96c996..000000000 --- a/lib/symfony/polyfill-php72/Php72.php +++ /dev/null @@ -1,217 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php72; - -/** - * @author Nicolas Grekas - * @author Dariusz Rumiński - * - * @internal - */ -final class Php72 -{ - private static $hashMask; - - public static function utf8_encode($s) - { - $s .= $s; - $len = \strlen($s); - - for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) { - switch (true) { - case $s[$i] < "\x80": $s[$j] = $s[$i]; break; - case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break; - default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break; - } - } - - return substr($s, 0, $j); - } - - public static function utf8_decode($s) - { - $s = (string) $s; - $len = \strlen($s); - - for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) { - switch ($s[$i] & "\xF0") { - case "\xC0": - case "\xD0": - $c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F"); - $s[$j] = $c < 256 ? \chr($c) : '?'; - break; - - case "\xF0": - ++$i; - // no break - - case "\xE0": - $s[$j] = '?'; - $i += 2; - break; - - default: - $s[$j] = $s[$i]; - } - } - - return substr($s, 0, $j); - } - - public static function php_os_family() - { - if ('\\' === \DIRECTORY_SEPARATOR) { - return 'Windows'; - } - - $map = [ - 'Darwin' => 'Darwin', - 'DragonFly' => 'BSD', - 'FreeBSD' => 'BSD', - 'NetBSD' => 'BSD', - 'OpenBSD' => 'BSD', - 'Linux' => 'Linux', - 'SunOS' => 'Solaris', - ]; - - return $map[\PHP_OS] ?? 'Unknown'; - } - - public static function spl_object_id($object) - { - if (null === self::$hashMask) { - self::initHashMask(); - } - if (null === $hash = spl_object_hash($object)) { - return; - } - - // On 32-bit systems, PHP_INT_SIZE is 4, - return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1)); - } - - public static function sapi_windows_vt100_support($stream, $enable = null) - { - if (!\is_resource($stream)) { - trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING); - - return false; - } - - $meta = stream_get_meta_data($stream); - - if ('STDIO' !== $meta['stream_type']) { - trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', \E_USER_WARNING); - - return false; - } - - // We cannot actually disable vt100 support if it is set - if (false === $enable || !self::stream_isatty($stream)) { - return false; - } - - // The native function does not apply to stdin - $meta = array_map('strtolower', $meta); - $stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri']; - - return !$stdin - && (false !== getenv('ANSICON') - || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM') - || 'Hyper' === getenv('TERM_PROGRAM')); - } - - public static function stream_isatty($stream) - { - if (!\is_resource($stream)) { - trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING); - - return false; - } - - if ('\\' === \DIRECTORY_SEPARATOR) { - $stat = @fstat($stream); - // Check if formatted mode is S_IFCHR - return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; - } - - return \function_exists('posix_isatty') && @posix_isatty($stream); - } - - private static function initHashMask() - { - $obj = (object) []; - self::$hashMask = -1; - - // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below - $obFuncs = ['ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush']; - foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? \DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) { - if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) { - $frame['line'] = 0; - break; - } - } - if (!empty($frame['line'])) { - ob_start(); - debug_zval_dump($obj); - self::$hashMask = (int) substr(ob_get_clean(), 17); - } - - self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1)); - } - - public static function mb_chr($code, $encoding = null) - { - if (0x80 > $code %= 0x200000) { - $s = \chr($code); - } elseif (0x800 > $code) { - $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); - } elseif (0x10000 > $code) { - $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } else { - $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } - - if ('UTF-8' !== $encoding = $encoding ?? mb_internal_encoding()) { - $s = mb_convert_encoding($s, $encoding, 'UTF-8'); - } - - return $s; - } - - public static function mb_ord($s, $encoding = null) - { - if (null === $encoding) { - $s = mb_convert_encoding($s, 'UTF-8'); - } elseif ('UTF-8' !== $encoding) { - $s = mb_convert_encoding($s, 'UTF-8', $encoding); - } - - if (1 === \strlen($s)) { - return \ord($s); - } - - $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; - if (0xF0 <= $code) { - return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; - } - if (0xE0 <= $code) { - return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; - } - if (0xC0 <= $code) { - return (($code - 0xC0) << 6) + $s[2] - 0x80; - } - - return $code; - } -} diff --git a/lib/symfony/polyfill-php72/README.md b/lib/symfony/polyfill-php72/README.md deleted file mode 100644 index ed1905055..000000000 --- a/lib/symfony/polyfill-php72/README.md +++ /dev/null @@ -1,35 +0,0 @@ -Symfony Polyfill / Php72 -======================== - -This component provides functions added to PHP 7.2 core: - -- [`spl_object_id`](https://php.net/spl_object_id) -- [`stream_isatty`](https://php.net/stream_isatty) - -And also functions added to PHP 7.2 mbstring: - -- [`mb_ord`](https://php.net/mb_ord) -- [`mb_chr`](https://php.net/mb_chr) -- [`mb_scrub`](https://php.net/mb_scrub) - -On Windows only: - -- [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support) - -Moved to core since 7.2 (was in the optional XML extension earlier): - -- [`utf8_encode`](https://php.net/utf8_encode) -- [`utf8_decode`](https://php.net/utf8_decode) - -Also, it provides constants added to PHP 7.2: - -- [`PHP_FLOAT_*`](https://php.net/reserved.constants#constant.php-float-dig) -- [`PHP_OS_FAMILY`](https://php.net/reserved.constants#constant.php-os-family) - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/lib/symfony/polyfill-php72/bootstrap.php b/lib/symfony/polyfill-php72/bootstrap.php deleted file mode 100644 index b5c92d4c7..000000000 --- a/lib/symfony/polyfill-php72/bootstrap.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php72 as p; - -if (\PHP_VERSION_ID >= 70200) { - return; -} - -if (!defined('PHP_FLOAT_DIG')) { - define('PHP_FLOAT_DIG', 15); -} -if (!defined('PHP_FLOAT_EPSILON')) { - define('PHP_FLOAT_EPSILON', 2.2204460492503E-16); -} -if (!defined('PHP_FLOAT_MIN')) { - define('PHP_FLOAT_MIN', 2.2250738585072E-308); -} -if (!defined('PHP_FLOAT_MAX')) { - define('PHP_FLOAT_MAX', 1.7976931348623157E+308); -} -if (!defined('PHP_OS_FAMILY')) { - define('PHP_OS_FAMILY', p\Php72::php_os_family()); -} - -if ('\\' === \DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) { - function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); } -} -if (!function_exists('stream_isatty')) { - function stream_isatty($stream) { return p\Php72::stream_isatty($stream); } -} -if (!function_exists('utf8_encode')) { - function utf8_encode($string) { return p\Php72::utf8_encode($string); } -} -if (!function_exists('utf8_decode')) { - function utf8_decode($string) { return p\Php72::utf8_decode($string); } -} -if (!function_exists('spl_object_id')) { - function spl_object_id($object) { return p\Php72::spl_object_id($object); } -} -if (!function_exists('mb_ord')) { - function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); } -} -if (!function_exists('mb_chr')) { - function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); } -} -if (!function_exists('mb_scrub')) { - function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } -} diff --git a/lib/symfony/polyfill-php72/composer.json b/lib/symfony/polyfill-php72/composer.json deleted file mode 100644 index b61b4c8a2..000000000 --- a/lib/symfony/polyfill-php72/composer.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "symfony/polyfill-php72", - "type": "library", - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "keywords": ["polyfill", "shim", "compatibility", "portable"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=7.1" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Php72\\": "" }, - "files": [ "bootstrap.php" ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} diff --git a/lib/symfony/polyfill-php80/PhpToken.php b/lib/symfony/polyfill-php80/PhpToken.php index fe6e69105..cd78c4ccc 100644 --- a/lib/symfony/polyfill-php80/PhpToken.php +++ b/lib/symfony/polyfill-php80/PhpToken.php @@ -29,7 +29,7 @@ class PhpToken implements \Stringable public $text; /** - * @var int + * @var -1|positive-int */ public $line; @@ -38,6 +38,9 @@ class PhpToken implements \Stringable */ public $pos; + /** + * @param -1|positive-int $line + */ public function __construct(int $id, string $text, int $line = -1, int $position = -1) { $this->id = $id; @@ -80,7 +83,7 @@ class PhpToken implements \Stringable } /** - * @return static[] + * @return list */ public static function tokenize(string $code, int $flags = 0): array { diff --git a/lib/symfony/polyfill-php80/composer.json b/lib/symfony/polyfill-php80/composer.json index f1801f403..a503b039a 100644 --- a/lib/symfony/polyfill-php80/composer.json +++ b/lib/symfony/polyfill-php80/composer.json @@ -20,7 +20,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, @@ -29,9 +29,6 @@ }, "minimum-stability": "dev", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" diff --git a/lib/symfony/service-contracts/Attribute/SubscribedService.php b/lib/symfony/service-contracts/Attribute/SubscribedService.php index d98e1dfdb..f850b8401 100644 --- a/lib/symfony/service-contracts/Attribute/SubscribedService.php +++ b/lib/symfony/service-contracts/Attribute/SubscribedService.php @@ -11,15 +11,15 @@ namespace Symfony\Contracts\Service\Attribute; +use Symfony\Contracts\Service\ServiceMethodsSubscriberTrait; use Symfony\Contracts\Service\ServiceSubscriberInterface; -use Symfony\Contracts\Service\ServiceSubscriberTrait; /** * For use as the return value for {@see ServiceSubscriberInterface}. * * @example new SubscribedService('http_client', HttpClientInterface::class, false, new Target('githubApi')) * - * Use with {@see ServiceSubscriberTrait} to mark a method's return type + * Use with {@see ServiceMethodsSubscriberTrait} to mark a method's return type * as a subscribed service. * * @author Kevin Bond diff --git a/lib/symfony/service-contracts/ServiceLocatorTrait.php b/lib/symfony/service-contracts/ServiceLocatorTrait.php index b62ec3e53..bbe454843 100644 --- a/lib/symfony/service-contracts/ServiceLocatorTrait.php +++ b/lib/symfony/service-contracts/ServiceLocatorTrait.php @@ -26,16 +26,15 @@ class_exists(NotFoundExceptionInterface::class); */ trait ServiceLocatorTrait { - private array $factories; private array $loading = []; private array $providedTypes; /** * @param array $factories */ - public function __construct(array $factories) - { - $this->factories = $factories; + public function __construct( + private array $factories, + ) { } public function has(string $id): bool @@ -91,16 +90,16 @@ trait ServiceLocatorTrait } else { $last = array_pop($alternatives); if ($alternatives) { - $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last); + $message = \sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last); } else { - $message = sprintf('only knows about the "%s" service.', $last); + $message = \sprintf('only knows about the "%s" service.', $last); } } if ($this->loading) { - $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message); + $message = \sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message); } else { - $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message); + $message = \sprintf('Service "%s" not found: the current service locator %s', $id, $message); } return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface { @@ -109,7 +108,7 @@ trait ServiceLocatorTrait private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface { - return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface { + return new class(\sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface { }; } } diff --git a/lib/symfony/service-contracts/ServiceSubscriberTrait.php b/lib/symfony/service-contracts/ServiceSubscriberTrait.php index f3b450cd6..ed4cec044 100644 --- a/lib/symfony/service-contracts/ServiceSubscriberTrait.php +++ b/lib/symfony/service-contracts/ServiceSubscriberTrait.php @@ -15,17 +15,23 @@ use Psr\Container\ContainerInterface; use Symfony\Contracts\Service\Attribute\Required; use Symfony\Contracts\Service\Attribute\SubscribedService; +trigger_deprecation('symfony/contracts', 'v3.5', '"%s" is deprecated, use "ServiceMethodsSubscriberTrait" instead.', ServiceSubscriberTrait::class); + /** - * Implementation of ServiceSubscriberInterface that determines subscribed services from - * method return types. Service ids are available as "ClassName::methodName". + * Implementation of ServiceSubscriberInterface that determines subscribed services + * from methods that have the #[SubscribedService] attribute. + * + * Service ids are available as "ClassName::methodName" so that the implementation + * of subscriber methods can be just `return $this->container->get(__METHOD__);`. + * + * @property ContainerInterface $container * * @author Kevin Bond + * + * @deprecated since symfony/contracts v3.5, use ServiceMethodsSubscriberTrait instead */ trait ServiceSubscriberTrait { - /** @var ContainerInterface */ - protected $container; - public static function getSubscribedServices(): array { $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; @@ -40,18 +46,18 @@ trait ServiceSubscriberTrait } if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { - throw new \LogicException(sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name)); + throw new \LogicException(\sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name)); } if (!$returnType = $method->getReturnType()) { - throw new \LogicException(sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class)); + throw new \LogicException(\sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class)); } /* @var SubscribedService $attribute */ $attribute = $attribute->newInstance(); $attribute->key ??= self::class.'::'.$method->name; $attribute->type ??= $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; - $attribute->nullable = $returnType->allowsNull(); + $attribute->nullable = $attribute->nullable ?: $returnType->allowsNull(); if ($attribute->attributes) { $services[] = $attribute; diff --git a/lib/symfony/service-contracts/composer.json b/lib/symfony/service-contracts/composer.json index 32bb8a316..bc2e99a8f 100644 --- a/lib/symfony/service-contracts/composer.json +++ b/lib/symfony/service-contracts/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -31,7 +32,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.6-dev" }, "thanks": { "name": "symfony/contracts", diff --git a/lib/webmozart/assert/CHANGELOG.md b/lib/webmozart/assert/CHANGELOG.md deleted file mode 100644 index 56c8011de..000000000 --- a/lib/webmozart/assert/CHANGELOG.md +++ /dev/null @@ -1,207 +0,0 @@ -Changelog -========= - -## UNRELEASED - -## 1.11.0 - -### Added - -* Added explicit (non magic) `allNullOr*` methods, with `@psalm-assert` annotations, for better Psalm support. - -### Changed - -* Trait methods will now check the assertion themselves, instead of using `__callStatic` -* `isList` will now deal correctly with (modified) lists that contain `NaN` -* `reportInvalidArgument` now has a return type of `never`. - -### Removed - -* Removed `symfony/polyfill-ctype` as a dependency, and require `ext-cytpe` instead. - * You can still require the `symfony/polyfill-ctype` in your project if you need it, as it provides `ext-ctype` - -## 1.10.0 - -### Added - -* On invalid assertion, we throw a `Webmozart\Assert\InvalidArgumentException` -* Added `Assert::positiveInteger()` - -### Changed - -* Using a trait with real implementations of `all*()` and `nullOr*()` methods to improve psalm compatibility. - -### Removed - -* Support for PHP <7.2 - -## 1.9.1 - -## Fixed - -* provisional support for PHP 8.0 - -## 1.9.0 - -* added better Psalm support for `all*` & `nullOr*` methods -* These methods are now understood by Psalm through a mixin. You may need a newer version of Psalm in order to use this -* added `@psalm-pure` annotation to `Assert::notFalse()` -* added more `@psalm-assert` annotations where appropriate - -## Changed - -* the `all*` & `nullOr*` methods are now declared on an interface, instead of `@method` annotations. -This interface is linked to the `Assert` class with a `@mixin` annotation. Most IDE's have supported this -for a long time, and you should not lose any autocompletion capabilities. PHPStan has supported this since -version `0.12.20`. This package is marked incompatible (with a composer conflict) with phpstan version prior to that. -If you do not use PHPStan than this does not matter. - -## 1.8.0 - -### Added - -* added `Assert::notStartsWith()` -* added `Assert::notEndsWith()` -* added `Assert::inArray()` -* added `@psalm-pure` annotations to pure assertions - -### Fixed - -* Exception messages of comparisons between `DateTime(Immutable)` objects now display their date & time. -* Custom Exception messages for `Assert::count()` now use the values to render the exception message. - -## 1.7.0 (2020-02-14) - -### Added - -* added `Assert::notFalse()` -* added `Assert::isAOf()` -* added `Assert::isAnyOf()` -* added `Assert::isNotA()` - -## 1.6.0 (2019-11-24) - -### Added - -* added `Assert::validArrayKey()` -* added `Assert::isNonEmptyList()` -* added `Assert::isNonEmptyMap()` -* added `@throws InvalidArgumentException` annotations to all methods that throw. -* added `@psalm-assert` for the list type to the `isList` assertion. - -### Fixed - -* `ResourceBundle` & `SimpleXMLElement` now pass the `isCountable` assertions. -They are countable, without implementing the `Countable` interface. -* The doc block of `range` now has the proper variables. -* An empty array will now pass `isList` and `isMap`. As it is a valid form of both. -If a non-empty variant is needed, use `isNonEmptyList` or `isNonEmptyMap`. - -### Changed - -* Removed some `@psalm-assert` annotations, that were 'side effect' assertions See: - * [#144](https://github.com/webmozart/assert/pull/144) - * [#145](https://github.com/webmozart/assert/issues/145) - * [#146](https://github.com/webmozart/assert/pull/146) - * [#150](https://github.com/webmozart/assert/pull/150) -* If you use Psalm, the minimum version needed is `3.6.0`. Which is enforced through a composer conflict. -If you don't use Psalm, then this has no impact. - -## 1.5.0 (2019-08-24) - -### Added - -* added `Assert::uniqueValues()` -* added `Assert::unicodeLetters()` -* added: `Assert::email()` -* added support for [Psalm](https://github.com/vimeo/psalm), by adding `@psalm-assert` annotations where appropriate. - -### Fixed - -* `Assert::endsWith()` would not give the correct result when dealing with a multibyte suffix. -* `Assert::length(), minLength, maxLength, lengthBetween` would not give the correct result when dealing with multibyte characters. - -**NOTE**: These 2 changes may break your assertions if you relied on the fact that multibyte characters didn't behave correctly. - -### Changed - -* The names of some variables have been updated to better reflect what they are. -* All function calls are now in their FQN form, slightly increasing performance. -* Tests are now properly ran against HHVM-3.30 and PHP nightly. - -### Deprecation - -* deprecated `Assert::isTraversable()` in favor of `Assert::isIterable()` - * This was already done in 1.3.0, but it was only done through a silenced `trigger_error`. It is now annotated as well. - -## 1.4.0 (2018-12-25) - -### Added - -* added `Assert::ip()` -* added `Assert::ipv4()` -* added `Assert::ipv6()` -* added `Assert::notRegex()` -* added `Assert::interfaceExists()` -* added `Assert::isList()` -* added `Assert::isMap()` -* added polyfill for ctype - -### Fixed - -* Special case when comparing objects implementing `__toString()` - -## 1.3.0 (2018-01-29) - -### Added - -* added `Assert::minCount()` -* added `Assert::maxCount()` -* added `Assert::countBetween()` -* added `Assert::isCountable()` -* added `Assert::notWhitespaceOnly()` -* added `Assert::natural()` -* added `Assert::notContains()` -* added `Assert::isArrayAccessible()` -* added `Assert::isInstanceOfAny()` -* added `Assert::isIterable()` - -### Fixed - -* `stringNotEmpty` will no longer report "0" is an empty string - -### Deprecation - -* deprecated `Assert::isTraversable()` in favor of `Assert::isIterable()` - -## 1.2.0 (2016-11-23) - - * added `Assert::throws()` - * added `Assert::count()` - * added extension point `Assert::reportInvalidArgument()` for custom subclasses - -## 1.1.0 (2016-08-09) - - * added `Assert::object()` - * added `Assert::propertyExists()` - * added `Assert::propertyNotExists()` - * added `Assert::methodExists()` - * added `Assert::methodNotExists()` - * added `Assert::uuid()` - -## 1.0.2 (2015-08-24) - - * integrated Style CI - * add tests for minimum package dependencies on Travis CI - -## 1.0.1 (2015-05-12) - - * added support for PHP 5.3.3 - -## 1.0.0 (2015-05-12) - - * first stable release - -## 1.0.0-beta (2015-03-19) - - * first beta release diff --git a/lib/webmozart/assert/README.md b/lib/webmozart/assert/README.md deleted file mode 100644 index 3b2397a1a..000000000 --- a/lib/webmozart/assert/README.md +++ /dev/null @@ -1,287 +0,0 @@ -Webmozart Assert -================ - -[![Latest Stable Version](https://poser.pugx.org/webmozart/assert/v/stable.svg)](https://packagist.org/packages/webmozart/assert) -[![Total Downloads](https://poser.pugx.org/webmozart/assert/downloads.svg)](https://packagist.org/packages/webmozart/assert) - -This library contains efficient assertions to test the input and output of -your methods. With these assertions, you can greatly reduce the amount of coding -needed to write a safe implementation. - -All assertions in the [`Assert`] class throw an `Webmozart\Assert\InvalidArgumentException` if -they fail. - -FAQ ---- - -**What's the difference to [beberlei/assert]?** - -This library is heavily inspired by Benjamin Eberlei's wonderful [assert package], -but fixes a usability issue with error messages that can't be fixed there without -breaking backwards compatibility. - -This package features usable error messages by default. However, you can also -easily write custom error messages: - -``` -Assert::string($path, 'The path is expected to be a string. Got: %s'); -``` - -In [beberlei/assert], the ordering of the `%s` placeholders is different for -every assertion. This package, on the contrary, provides consistent placeholder -ordering for all assertions: - -* `%s`: The tested value as string, e.g. `"/foo/bar"`. -* `%2$s`, `%3$s`, ...: Additional assertion-specific values, e.g. the - minimum/maximum length, allowed values, etc. - -Check the source code of the assertions to find out details about the additional -available placeholders. - -Installation ------------- - -Use [Composer] to install the package: - -```bash -composer require webmozart/assert -``` - -Example -------- - -```php -use Webmozart\Assert\Assert; - -class Employee -{ - public function __construct($id) - { - Assert::integer($id, 'The employee ID must be an integer. Got: %s'); - Assert::greaterThan($id, 0, 'The employee ID must be a positive integer. Got: %s'); - } -} -``` - -If you create an employee with an invalid ID, an exception is thrown: - -```php -new Employee('foobar'); -// => Webmozart\Assert\InvalidArgumentException: -// The employee ID must be an integer. Got: string - -new Employee(-10); -// => Webmozart\Assert\InvalidArgumentException: -// The employee ID must be a positive integer. Got: -10 -``` - -Assertions ----------- - -The [`Assert`] class provides the following assertions: - -### Type Assertions - -Method | Description --------------------------------------------------------- | -------------------------------------------------- -`string($value, $message = '')` | Check that a value is a string -`stringNotEmpty($value, $message = '')` | Check that a value is a non-empty string -`integer($value, $message = '')` | Check that a value is an integer -`integerish($value, $message = '')` | Check that a value casts to an integer -`positiveInteger($value, $message = '')` | Check that a value is a positive (non-zero) integer -`float($value, $message = '')` | Check that a value is a float -`numeric($value, $message = '')` | Check that a value is numeric -`natural($value, $message= ''')` | Check that a value is a non-negative integer -`boolean($value, $message = '')` | Check that a value is a boolean -`scalar($value, $message = '')` | Check that a value is a scalar -`object($value, $message = '')` | Check that a value is an object -`resource($value, $type = null, $message = '')` | Check that a value is a resource -`isCallable($value, $message = '')` | Check that a value is a callable -`isArray($value, $message = '')` | Check that a value is an array -`isTraversable($value, $message = '')` (deprecated) | Check that a value is an array or a `\Traversable` -`isIterable($value, $message = '')` | Check that a value is an array or a `\Traversable` -`isCountable($value, $message = '')` | Check that a value is an array or a `\Countable` -`isInstanceOf($value, $class, $message = '')` | Check that a value is an `instanceof` a class -`isInstanceOfAny($value, array $classes, $message = '')` | Check that a value is an `instanceof` at least one class on the array of classes -`notInstanceOf($value, $class, $message = '')` | Check that a value is not an `instanceof` a class -`isAOf($value, $class, $message = '')` | Check that a value is of the class or has one of its parents -`isAnyOf($value, array $classes, $message = '')` | Check that a value is of at least one of the classes or has one of its parents -`isNotA($value, $class, $message = '')` | Check that a value is not of the class or has not one of its parents -`isArrayAccessible($value, $message = '')` | Check that a value can be accessed as an array -`uniqueValues($values, $message = '')` | Check that the given array contains unique values - -### Comparison Assertions - -Method | Description ------------------------------------------------ | ------------------------------------------------------------------ -`true($value, $message = '')` | Check that a value is `true` -`false($value, $message = '')` | Check that a value is `false` -`notFalse($value, $message = '')` | Check that a value is not `false` -`null($value, $message = '')` | Check that a value is `null` -`notNull($value, $message = '')` | Check that a value is not `null` -`isEmpty($value, $message = '')` | Check that a value is `empty()` -`notEmpty($value, $message = '')` | Check that a value is not `empty()` -`eq($value, $value2, $message = '')` | Check that a value equals another (`==`) -`notEq($value, $value2, $message = '')` | Check that a value does not equal another (`!=`) -`same($value, $value2, $message = '')` | Check that a value is identical to another (`===`) -`notSame($value, $value2, $message = '')` | Check that a value is not identical to another (`!==`) -`greaterThan($value, $value2, $message = '')` | Check that a value is greater than another -`greaterThanEq($value, $value2, $message = '')` | Check that a value is greater than or equal to another -`lessThan($value, $value2, $message = '')` | Check that a value is less than another -`lessThanEq($value, $value2, $message = '')` | Check that a value is less than or equal to another -`range($value, $min, $max, $message = '')` | Check that a value is within a range -`inArray($value, array $values, $message = '')` | Check that a value is one of a list of values -`oneOf($value, array $values, $message = '')` | Check that a value is one of a list of values (alias of `inArray`) - -### String Assertions - -You should check that a value is a string with `Assert::string()` before making -any of the following assertions. - -Method | Description ---------------------------------------------------- | ----------------------------------------------------------------- -`contains($value, $subString, $message = '')` | Check that a string contains a substring -`notContains($value, $subString, $message = '')` | Check that a string does not contain a substring -`startsWith($value, $prefix, $message = '')` | Check that a string has a prefix -`notStartsWith($value, $prefix, $message = '')` | Check that a string does not have a prefix -`startsWithLetter($value, $message = '')` | Check that a string starts with a letter -`endsWith($value, $suffix, $message = '')` | Check that a string has a suffix -`notEndsWith($value, $suffix, $message = '')` | Check that a string does not have a suffix -`regex($value, $pattern, $message = '')` | Check that a string matches a regular expression -`notRegex($value, $pattern, $message = '')` | Check that a string does not match a regular expression -`unicodeLetters($value, $message = '')` | Check that a string contains Unicode letters only -`alpha($value, $message = '')` | Check that a string contains letters only -`digits($value, $message = '')` | Check that a string contains digits only -`alnum($value, $message = '')` | Check that a string contains letters and digits only -`lower($value, $message = '')` | Check that a string contains lowercase characters only -`upper($value, $message = '')` | Check that a string contains uppercase characters only -`length($value, $length, $message = '')` | Check that a string has a certain number of characters -`minLength($value, $min, $message = '')` | Check that a string has at least a certain number of characters -`maxLength($value, $max, $message = '')` | Check that a string has at most a certain number of characters -`lengthBetween($value, $min, $max, $message = '')` | Check that a string has a length in the given range -`uuid($value, $message = '')` | Check that a string is a valid UUID -`ip($value, $message = '')` | Check that a string is a valid IP (either IPv4 or IPv6) -`ipv4($value, $message = '')` | Check that a string is a valid IPv4 -`ipv6($value, $message = '')` | Check that a string is a valid IPv6 -`email($value, $message = '')` | Check that a string is a valid e-mail address -`notWhitespaceOnly($value, $message = '')` | Check that a string contains at least one non-whitespace character - -### File Assertions - -Method | Description ------------------------------------ | -------------------------------------------------- -`fileExists($value, $message = '')` | Check that a value is an existing path -`file($value, $message = '')` | Check that a value is an existing file -`directory($value, $message = '')` | Check that a value is an existing directory -`readable($value, $message = '')` | Check that a value is a readable path -`writable($value, $message = '')` | Check that a value is a writable path - -### Object Assertions - -Method | Description ------------------------------------------------------ | -------------------------------------------------- -`classExists($value, $message = '')` | Check that a value is an existing class name -`subclassOf($value, $class, $message = '')` | Check that a class is a subclass of another -`interfaceExists($value, $message = '')` | Check that a value is an existing interface name -`implementsInterface($value, $class, $message = '')` | Check that a class implements an interface -`propertyExists($value, $property, $message = '')` | Check that a property exists in a class/object -`propertyNotExists($value, $property, $message = '')` | Check that a property does not exist in a class/object -`methodExists($value, $method, $message = '')` | Check that a method exists in a class/object -`methodNotExists($value, $method, $message = '')` | Check that a method does not exist in a class/object - -### Array Assertions - -Method | Description --------------------------------------------------- | ------------------------------------------------------------------ -`keyExists($array, $key, $message = '')` | Check that a key exists in an array -`keyNotExists($array, $key, $message = '')` | Check that a key does not exist in an array -`validArrayKey($key, $message = '')` | Check that a value is a valid array key (int or string) -`count($array, $number, $message = '')` | Check that an array contains a specific number of elements -`minCount($array, $min, $message = '')` | Check that an array contains at least a certain number of elements -`maxCount($array, $max, $message = '')` | Check that an array contains at most a certain number of elements -`countBetween($array, $min, $max, $message = '')` | Check that an array has a count in the given range -`isList($array, $message = '')` | Check that an array is a non-associative list -`isNonEmptyList($array, $message = '')` | Check that an array is a non-associative list, and not empty -`isMap($array, $message = '')` | Check that an array is associative and has strings as keys -`isNonEmptyMap($array, $message = '')` | Check that an array is associative and has strings as keys, and is not empty - -### Function Assertions - -Method | Description -------------------------------------------- | ----------------------------------------------------------------------------------------------------- -`throws($closure, $class, $message = '')` | Check that a function throws a certain exception. Subclasses of the exception class will be accepted. - -### Collection Assertions - -All of the above assertions can be prefixed with `all*()` to test the contents -of an array or a `\Traversable`: - -```php -Assert::allIsInstanceOf($employees, 'Acme\Employee'); -``` - -### Nullable Assertions - -All of the above assertions can be prefixed with `nullOr*()` to run the -assertion only if it the value is not `null`: - -```php -Assert::nullOrString($middleName, 'The middle name must be a string or null. Got: %s'); -``` - -### Extending Assert - -The `Assert` class comes with a few methods, which can be overridden to change the class behaviour. You can also extend it to -add your own assertions. - -#### Overriding methods - -Overriding the following methods in your assertion class allows you to change the behaviour of the assertions: - -* `public static function __callStatic($name, $arguments)` - * This method is used to 'create' the `nullOr` and `all` versions of the assertions. -* `protected static function valueToString($value)` - * This method is used for error messages, to convert the value to a string value for displaying. You could use this for representing a value object with a `__toString` method for example. -* `protected static function typeToString($value)` - * This method is used for error messages, to convert the a value to a string representing its type. -* `protected static function strlen($value)` - * This method is used to calculate string length for relevant methods, using the `mb_strlen` if available and useful. -* `protected static function reportInvalidArgument($message)` - * This method is called when an assertion fails, with the specified error message. Here you can throw your own exception, or log something. - -## Static analysis support - -Where applicable, assertion functions are annotated to support Psalm's -[Assertion syntax](https://psalm.dev/docs/annotating_code/assertion_syntax/). -A dedicated [PHPStan Plugin](https://github.com/phpstan/phpstan-webmozart-assert) is -required for proper type support. - -Authors -------- - -* [Bernhard Schussek] a.k.a. [@webmozart] -* [The Community Contributors] - -Contribute ----------- - -Contributions to the package are always welcome! - -* Report any bugs or issues you find on the [issue tracker]. -* You can grab the source code at the package's [Git repository]. - -License -------- - -All contents of this package are licensed under the [MIT license]. - -[beberlei/assert]: https://github.com/beberlei/assert -[assert package]: https://github.com/beberlei/assert -[Composer]: https://getcomposer.org -[Bernhard Schussek]: https://webmozarts.com -[The Community Contributors]: https://github.com/webmozart/assert/graphs/contributors -[issue tracker]: https://github.com/webmozart/assert/issues -[Git repository]: https://github.com/webmozart/assert -[@webmozart]: https://twitter.com/webmozart -[MIT license]: LICENSE -[`Assert`]: src/Assert.php diff --git a/lib/webmozart/assert/composer.json b/lib/webmozart/assert/composer.json deleted file mode 100644 index b340452c7..000000000 --- a/lib/webmozart/assert/composer.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "webmozart/assert", - "description": "Assertions to validate method input/output with nice error messages.", - "license": "MIT", - "keywords": [ - "assert", - "check", - "validate" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "require": { - "php": "^7.2 || ^8.0", - "ext-ctype": "*" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Webmozart\\Assert\\Tests\\": "tests/", - "Webmozart\\Assert\\Bin\\": "bin/src" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - } -} diff --git a/lib/webmozart/assert/src/Assert.php b/lib/webmozart/assert/src/Assert.php deleted file mode 100644 index db1f3a51a..000000000 --- a/lib/webmozart/assert/src/Assert.php +++ /dev/null @@ -1,2080 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Webmozart\Assert; - -use ArrayAccess; -use BadMethodCallException; -use Closure; -use Countable; -use DateTime; -use DateTimeImmutable; -use Exception; -use ResourceBundle; -use SimpleXMLElement; -use Throwable; -use Traversable; - -/** - * Efficient assertions to validate the input/output of your methods. - * - * @since 1.0 - * - * @author Bernhard Schussek - */ -class Assert -{ - use Mixin; - - /** - * @psalm-pure - * @psalm-assert string $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function string($value, $message = '') - { - if (!\is_string($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a string. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert non-empty-string $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function stringNotEmpty($value, $message = '') - { - static::string($value, $message); - static::notEq($value, '', $message); - } - - /** - * @psalm-pure - * @psalm-assert int $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function integer($value, $message = '') - { - if (!\is_int($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an integer. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert numeric $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function integerish($value, $message = '') - { - if (!\is_numeric($value) || $value != (int) $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an integerish value. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert positive-int $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function positiveInteger($value, $message = '') - { - if (!(\is_int($value) && $value > 0)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a positive integer. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert float $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function float($value, $message = '') - { - if (!\is_float($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a float. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert numeric $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function numeric($value, $message = '') - { - if (!\is_numeric($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a numeric. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert positive-int|0 $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function natural($value, $message = '') - { - if (!\is_int($value) || $value < 0) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a non-negative integer. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert bool $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function boolean($value, $message = '') - { - if (!\is_bool($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a boolean. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert scalar $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function scalar($value, $message = '') - { - if (!\is_scalar($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a scalar. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert object $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function object($value, $message = '') - { - if (!\is_object($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an object. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert resource $value - * - * @param mixed $value - * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function resource($value, $type = null, $message = '') - { - if (!\is_resource($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a resource. Got: %s', - static::typeToString($value) - )); - } - - if ($type && $type !== \get_resource_type($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a resource of type %2$s. Got: %s', - static::typeToString($value), - $type - )); - } - } - - /** - * @psalm-pure - * @psalm-assert callable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isCallable($value, $message = '') - { - if (!\is_callable($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a callable. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert array $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isArray($value, $message = '') - { - if (!\is_array($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @deprecated use "isIterable" or "isInstanceOf" instead - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isTraversable($value, $message = '') - { - @\trigger_error( - \sprintf( - 'The "%s" assertion is deprecated. You should stop using it, as it will soon be removed in 2.0 version. Use "isIterable" or "isInstanceOf" instead.', - __METHOD__ - ), - \E_USER_DEPRECATED - ); - - if (!\is_array($value) && !($value instanceof Traversable)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a traversable. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert array|ArrayAccess $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isArrayAccessible($value, $message = '') - { - if (!\is_array($value) && !($value instanceof ArrayAccess)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array accessible. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert countable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isCountable($value, $message = '') - { - if ( - !\is_array($value) - && !($value instanceof Countable) - && !($value instanceof ResourceBundle) - && !($value instanceof SimpleXMLElement) - ) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a countable. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isIterable($value, $message = '') - { - if (!\is_array($value) && !($value instanceof Traversable)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an iterable. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert ExpectedType $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isInstanceOf($value, $class, $message = '') - { - if (!($value instanceof $class)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an instance of %2$s. Got: %s', - static::typeToString($value), - $class - )); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert !ExpectedType $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notInstanceOf($value, $class, $message = '') - { - if ($value instanceof $class) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an instance other than %2$s. Got: %s', - static::typeToString($value), - $class - )); - } - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param mixed $value - * @param array $classes - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isInstanceOfAny($value, array $classes, $message = '') - { - foreach ($classes as $class) { - if ($value instanceof $class) { - return; - } - } - - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an instance of any of %2$s. Got: %s', - static::typeToString($value), - \implode(', ', \array_map(array(static::class, 'valueToString'), $classes)) - )); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert ExpectedType|class-string $value - * - * @param object|string $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isAOf($value, $class, $message = '') - { - static::string($class, 'Expected class as a string. Got: %s'); - - if (!\is_a($value, $class, \is_string($value))) { - static::reportInvalidArgument(sprintf( - $message ?: 'Expected an instance of this class or to this class among its parents "%2$s". Got: %s', - static::valueToString($value), - $class - )); - } - } - - /** - * @psalm-pure - * @psalm-template UnexpectedType of object - * @psalm-param class-string $class - * @psalm-assert !UnexpectedType $value - * @psalm-assert !class-string $value - * - * @param object|string $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isNotA($value, $class, $message = '') - { - static::string($class, 'Expected class as a string. Got: %s'); - - if (\is_a($value, $class, \is_string($value))) { - static::reportInvalidArgument(sprintf( - $message ?: 'Expected an instance of this class or to this class among its parents other than "%2$s". Got: %s', - static::valueToString($value), - $class - )); - } - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param object|string $value - * @param string[] $classes - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isAnyOf($value, array $classes, $message = '') - { - foreach ($classes as $class) { - static::string($class, 'Expected class as a string. Got: %s'); - - if (\is_a($value, $class, \is_string($value))) { - return; - } - } - - static::reportInvalidArgument(sprintf( - $message ?: 'Expected an instance of any of this classes or any of those classes among their parents "%2$s". Got: %s', - static::valueToString($value), - \implode(', ', $classes) - )); - } - - /** - * @psalm-pure - * @psalm-assert empty $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isEmpty($value, $message = '') - { - if (!empty($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an empty value. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert !empty $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notEmpty($value, $message = '') - { - if (empty($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a non-empty value. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function null($value, $message = '') - { - if (null !== $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected null. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert !null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notNull($value, $message = '') - { - if (null === $value) { - static::reportInvalidArgument( - $message ?: 'Expected a value other than null.' - ); - } - } - - /** - * @psalm-pure - * @psalm-assert true $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function true($value, $message = '') - { - if (true !== $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be true. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert false $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function false($value, $message = '') - { - if (false !== $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be false. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert !false $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notFalse($value, $message = '') - { - if (false === $value) { - static::reportInvalidArgument( - $message ?: 'Expected a value other than false.' - ); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function ip($value, $message = '') - { - if (false === \filter_var($value, \FILTER_VALIDATE_IP)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be an IP. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function ipv4($value, $message = '') - { - if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be an IPv4. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function ipv6($value, $message = '') - { - if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be an IPv6. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function email($value, $message = '') - { - if (false === \filter_var($value, FILTER_VALIDATE_EMAIL)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be a valid e-mail address. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * Does non strict comparisons on the items, so ['3', 3] will not pass the assertion. - * - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function uniqueValues(array $values, $message = '') - { - $allValues = \count($values); - $uniqueValues = \count(\array_unique($values)); - - if ($allValues !== $uniqueValues) { - $difference = $allValues - $uniqueValues; - - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array of unique values, but %s of them %s duplicated', - $difference, - (1 === $difference ? 'is' : 'are') - )); - } - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function eq($value, $expect, $message = '') - { - if ($expect != $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value equal to %2$s. Got: %s', - static::valueToString($value), - static::valueToString($expect) - )); - } - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notEq($value, $expect, $message = '') - { - if ($expect == $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a different value than %s.', - static::valueToString($expect) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function same($value, $expect, $message = '') - { - if ($expect !== $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value identical to %2$s. Got: %s', - static::valueToString($value), - static::valueToString($expect) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notSame($value, $expect, $message = '') - { - if ($expect === $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value not identical to %s.', - static::valueToString($expect) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function greaterThan($value, $limit, $message = '') - { - if ($value <= $limit) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value greater than %2$s. Got: %s', - static::valueToString($value), - static::valueToString($limit) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function greaterThanEq($value, $limit, $message = '') - { - if ($value < $limit) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value greater than or equal to %2$s. Got: %s', - static::valueToString($value), - static::valueToString($limit) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function lessThan($value, $limit, $message = '') - { - if ($value >= $limit) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value less than %2$s. Got: %s', - static::valueToString($value), - static::valueToString($limit) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function lessThanEq($value, $limit, $message = '') - { - if ($value > $limit) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value less than or equal to %2$s. Got: %s', - static::valueToString($value), - static::valueToString($limit) - )); - } - } - - /** - * Inclusive range, so Assert::(3, 3, 5) passes. - * - * @psalm-pure - * - * @param mixed $value - * @param mixed $min - * @param mixed $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function range($value, $min, $max, $message = '') - { - if ($value < $min || $value > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value between %2$s and %3$s. Got: %s', - static::valueToString($value), - static::valueToString($min), - static::valueToString($max) - )); - } - } - - /** - * A more human-readable alias of Assert::inArray(). - * - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function oneOf($value, array $values, $message = '') - { - static::inArray($value, $values, $message); - } - - /** - * Does strict comparison, so Assert::inArray(3, ['3']) does not pass the assertion. - * - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function inArray($value, array $values, $message = '') - { - if (!\in_array($value, $values, true)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected one of: %2$s. Got: %s', - static::valueToString($value), - \implode(', ', \array_map(array(static::class, 'valueToString'), $values)) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function contains($value, $subString, $message = '') - { - if (false === \strpos($value, $subString)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain %2$s. Got: %s', - static::valueToString($value), - static::valueToString($subString) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notContains($value, $subString, $message = '') - { - if (false !== \strpos($value, $subString)) { - static::reportInvalidArgument(\sprintf( - $message ?: '%2$s was not expected to be contained in a value. Got: %s', - static::valueToString($value), - static::valueToString($subString) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notWhitespaceOnly($value, $message = '') - { - if (\preg_match('/^\s*$/', $value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a non-whitespace string. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function startsWith($value, $prefix, $message = '') - { - if (0 !== \strpos($value, $prefix)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to start with %2$s. Got: %s', - static::valueToString($value), - static::valueToString($prefix) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notStartsWith($value, $prefix, $message = '') - { - if (0 === \strpos($value, $prefix)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value not to start with %2$s. Got: %s', - static::valueToString($value), - static::valueToString($prefix) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function startsWithLetter($value, $message = '') - { - static::string($value); - - $valid = isset($value[0]); - - if ($valid) { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = \ctype_alpha($value[0]); - \setlocale(LC_CTYPE, $locale); - } - - if (!$valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to start with a letter. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function endsWith($value, $suffix, $message = '') - { - if ($suffix !== \substr($value, -\strlen($suffix))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to end with %2$s. Got: %s', - static::valueToString($value), - static::valueToString($suffix) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notEndsWith($value, $suffix, $message = '') - { - if ($suffix === \substr($value, -\strlen($suffix))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value not to end with %2$s. Got: %s', - static::valueToString($value), - static::valueToString($suffix) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function regex($value, $pattern, $message = '') - { - if (!\preg_match($pattern, $value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The value %s does not match the expected pattern.', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notRegex($value, $pattern, $message = '') - { - if (\preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The value %s matches the pattern %s (at offset %d).', - static::valueToString($value), - static::valueToString($pattern), - $matches[0][1] - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function unicodeLetters($value, $message = '') - { - static::string($value); - - if (!\preg_match('/^\p{L}+$/u', $value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain only Unicode letters. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function alpha($value, $message = '') - { - static::string($value); - - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_alpha($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain only letters. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function digits($value, $message = '') - { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_digit($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain digits only. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function alnum($value, $message = '') - { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_alnum($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain letters and digits only. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert lowercase-string $value - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function lower($value, $message = '') - { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_lower($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain lowercase characters only. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert !lowercase-string $value - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function upper($value, $message = '') - { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_upper($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain uppercase characters only. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param int $length - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function length($value, $length, $message = '') - { - if ($length !== static::strlen($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain %2$s characters. Got: %s', - static::valueToString($value), - $length - )); - } - } - - /** - * Inclusive min. - * - * @psalm-pure - * - * @param string $value - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function minLength($value, $min, $message = '') - { - if (static::strlen($value) < $min) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain at least %2$s characters. Got: %s', - static::valueToString($value), - $min - )); - } - } - - /** - * Inclusive max. - * - * @psalm-pure - * - * @param string $value - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function maxLength($value, $max, $message = '') - { - if (static::strlen($value) > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain at most %2$s characters. Got: %s', - static::valueToString($value), - $max - )); - } - } - - /** - * Inclusive , so Assert::lengthBetween('asd', 3, 5); passes the assertion. - * - * @psalm-pure - * - * @param string $value - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function lengthBetween($value, $min, $max, $message = '') - { - $length = static::strlen($value); - - if ($length < $min || $length > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s', - static::valueToString($value), - $min, - $max - )); - } - } - - /** - * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file. - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function fileExists($value, $message = '') - { - static::string($value); - - if (!\file_exists($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The file %s does not exist.', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function file($value, $message = '') - { - static::fileExists($value, $message); - - if (!\is_file($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The path %s is not a file.', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function directory($value, $message = '') - { - static::fileExists($value, $message); - - if (!\is_dir($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The path %s is no directory.', - static::valueToString($value) - )); - } - } - - /** - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function readable($value, $message = '') - { - if (!\is_readable($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The path %s is not readable.', - static::valueToString($value) - )); - } - } - - /** - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function writable($value, $message = '') - { - if (!\is_writable($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The path %s is not writable.', - static::valueToString($value) - )); - } - } - - /** - * @psalm-assert class-string $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function classExists($value, $message = '') - { - if (!\class_exists($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an existing class name. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert class-string|ExpectedType $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function subclassOf($value, $class, $message = '') - { - if (!\is_subclass_of($value, $class)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a sub-class of %2$s. Got: %s', - static::valueToString($value), - static::valueToString($class) - )); - } - } - - /** - * @psalm-assert class-string $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function interfaceExists($value, $message = '') - { - if (!\interface_exists($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an existing interface name. got %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $interface - * @psalm-assert class-string $value - * - * @param mixed $value - * @param mixed $interface - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function implementsInterface($value, $interface, $message = '') - { - if (!\in_array($interface, \class_implements($value))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an implementation of %2$s. Got: %s', - static::valueToString($value), - static::valueToString($interface) - )); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object $classOrObject - * - * @param string|object $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function propertyExists($classOrObject, $property, $message = '') - { - if (!\property_exists($classOrObject, $property)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the property %s to exist.', - static::valueToString($property) - )); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object $classOrObject - * - * @param string|object $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function propertyNotExists($classOrObject, $property, $message = '') - { - if (\property_exists($classOrObject, $property)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the property %s to not exist.', - static::valueToString($property) - )); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object $classOrObject - * - * @param string|object $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function methodExists($classOrObject, $method, $message = '') - { - if (!(\is_string($classOrObject) || \is_object($classOrObject)) || !\method_exists($classOrObject, $method)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the method %s to exist.', - static::valueToString($method) - )); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object $classOrObject - * - * @param string|object $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function methodNotExists($classOrObject, $method, $message = '') - { - if ((\is_string($classOrObject) || \is_object($classOrObject)) && \method_exists($classOrObject, $method)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the method %s to not exist.', - static::valueToString($method) - )); - } - } - - /** - * @psalm-pure - * - * @param array $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function keyExists($array, $key, $message = '') - { - if (!(isset($array[$key]) || \array_key_exists($key, $array))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the key %s to exist.', - static::valueToString($key) - )); - } - } - - /** - * @psalm-pure - * - * @param array $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function keyNotExists($array, $key, $message = '') - { - if (isset($array[$key]) || \array_key_exists($key, $array)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the key %s to not exist.', - static::valueToString($key) - )); - } - } - - /** - * Checks if a value is a valid array key (int or string). - * - * @psalm-pure - * @psalm-assert array-key $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function validArrayKey($value, $message = '') - { - if (!(\is_int($value) || \is_string($value))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected string or integer. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * Does not check if $array is countable, this can generate a warning on php versions after 7.2. - * - * @param Countable|array $array - * @param int $number - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function count($array, $number, $message = '') - { - static::eq( - \count($array), - $number, - \sprintf( - $message ?: 'Expected an array to contain %d elements. Got: %d.', - $number, - \count($array) - ) - ); - } - - /** - * Does not check if $array is countable, this can generate a warning on php versions after 7.2. - * - * @param Countable|array $array - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function minCount($array, $min, $message = '') - { - if (\count($array) < $min) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array to contain at least %2$d elements. Got: %d', - \count($array), - $min - )); - } - } - - /** - * Does not check if $array is countable, this can generate a warning on php versions after 7.2. - * - * @param Countable|array $array - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function maxCount($array, $max, $message = '') - { - if (\count($array) > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array to contain at most %2$d elements. Got: %d', - \count($array), - $max - )); - } - } - - /** - * Does not check if $array is countable, this can generate a warning on php versions after 7.2. - * - * @param Countable|array $array - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function countBetween($array, $min, $max, $message = '') - { - $count = \count($array); - - if ($count < $min || $count > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d', - $count, - $min, - $max - )); - } - } - - /** - * @psalm-pure - * @psalm-assert list $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isList($array, $message = '') - { - if (!\is_array($array)) { - static::reportInvalidArgument( - $message ?: 'Expected list - non-associative array.' - ); - } - - if ($array === \array_values($array)) { - return; - } - - $nextKey = -1; - foreach ($array as $k => $v) { - if ($k !== ++$nextKey) { - static::reportInvalidArgument( - $message ?: 'Expected list - non-associative array.' - ); - } - } - } - - /** - * @psalm-pure - * @psalm-assert non-empty-list $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isNonEmptyList($array, $message = '') - { - static::isList($array, $message); - static::notEmpty($array, $message); - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param mixed|array $array - * @psalm-assert array $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isMap($array, $message = '') - { - if ( - !\is_array($array) || - \array_keys($array) !== \array_filter(\array_keys($array), '\is_string') - ) { - static::reportInvalidArgument( - $message ?: 'Expected map - associative array with string keys.' - ); - } - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param mixed|array $array - * @psalm-assert array $array - * @psalm-assert !empty $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isNonEmptyMap($array, $message = '') - { - static::isMap($array, $message); - static::notEmpty($array, $message); - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function uuid($value, $message = '') - { - $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value); - - // The nil UUID is special form of UUID that is specified to have all - // 128 bits set to zero. - if ('00000000-0000-0000-0000-000000000000' === $value) { - return; - } - - if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Value %s is not a valid UUID.', - static::valueToString($value) - )); - } - } - - /** - * @psalm-param class-string $class - * - * @param Closure $expression - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function throws(Closure $expression, $class = 'Exception', $message = '') - { - static::string($class); - - $actual = 'none'; - - try { - $expression(); - } catch (Exception $e) { - $actual = \get_class($e); - if ($e instanceof $class) { - return; - } - } catch (Throwable $e) { - $actual = \get_class($e); - if ($e instanceof $class) { - return; - } - } - - static::reportInvalidArgument($message ?: \sprintf( - 'Expected to throw "%s", got "%s"', - $class, - $actual - )); - } - - /** - * @throws BadMethodCallException - */ - public static function __callStatic($name, $arguments) - { - if ('nullOr' === \substr($name, 0, 6)) { - if (null !== $arguments[0]) { - $method = \lcfirst(\substr($name, 6)); - \call_user_func_array(array(static::class, $method), $arguments); - } - - return; - } - - if ('all' === \substr($name, 0, 3)) { - static::isIterable($arguments[0]); - - $method = \lcfirst(\substr($name, 3)); - $args = $arguments; - - foreach ($arguments[0] as $entry) { - $args[0] = $entry; - - \call_user_func_array(array(static::class, $method), $args); - } - - return; - } - - throw new BadMethodCallException('No such method: '.$name); - } - - /** - * @param mixed $value - * - * @return string - */ - protected static function valueToString($value) - { - if (null === $value) { - return 'null'; - } - - if (true === $value) { - return 'true'; - } - - if (false === $value) { - return 'false'; - } - - if (\is_array($value)) { - return 'array'; - } - - if (\is_object($value)) { - if (\method_exists($value, '__toString')) { - return \get_class($value).': '.self::valueToString($value->__toString()); - } - - if ($value instanceof DateTime || $value instanceof DateTimeImmutable) { - return \get_class($value).': '.self::valueToString($value->format('c')); - } - - return \get_class($value); - } - - if (\is_resource($value)) { - return 'resource'; - } - - if (\is_string($value)) { - return '"'.$value.'"'; - } - - return (string) $value; - } - - /** - * @param mixed $value - * - * @return string - */ - protected static function typeToString($value) - { - return \is_object($value) ? \get_class($value) : \gettype($value); - } - - protected static function strlen($value) - { - if (!\function_exists('mb_detect_encoding')) { - return \strlen($value); - } - - if (false === $encoding = \mb_detect_encoding($value)) { - return \strlen($value); - } - - return \mb_strlen($value, $encoding); - } - - /** - * @param string $message - * - * @throws InvalidArgumentException - * - * @psalm-pure this method is not supposed to perform side-effects - * @psalm-return never - */ - protected static function reportInvalidArgument($message) - { - throw new InvalidArgumentException($message); - } - - private function __construct() - { - } -} diff --git a/lib/webmozart/assert/src/InvalidArgumentException.php b/lib/webmozart/assert/src/InvalidArgumentException.php deleted file mode 100644 index 9d95a58c5..000000000 --- a/lib/webmozart/assert/src/InvalidArgumentException.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Webmozart\Assert; - -class InvalidArgumentException extends \InvalidArgumentException -{ -} diff --git a/lib/webmozart/assert/src/Mixin.php b/lib/webmozart/assert/src/Mixin.php deleted file mode 100644 index 0f0a75e33..000000000 --- a/lib/webmozart/assert/src/Mixin.php +++ /dev/null @@ -1,5089 +0,0 @@ - $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allString($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::string($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrString($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::string($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert non-empty-string|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrStringNotEmpty($value, $message = '') - { - null === $value || static::stringNotEmpty($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allStringNotEmpty($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::stringNotEmpty($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrStringNotEmpty($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::stringNotEmpty($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert int|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrInteger($value, $message = '') - { - null === $value || static::integer($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allInteger($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::integer($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrInteger($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::integer($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert numeric|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIntegerish($value, $message = '') - { - null === $value || static::integerish($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIntegerish($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::integerish($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIntegerish($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::integerish($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert positive-int|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrPositiveInteger($value, $message = '') - { - null === $value || static::positiveInteger($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allPositiveInteger($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::positiveInteger($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrPositiveInteger($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::positiveInteger($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert float|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrFloat($value, $message = '') - { - null === $value || static::float($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allFloat($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::float($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrFloat($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::float($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert numeric|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNumeric($value, $message = '') - { - null === $value || static::numeric($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNumeric($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::numeric($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNumeric($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::numeric($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert positive-int|0|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNatural($value, $message = '') - { - null === $value || static::natural($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNatural($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::natural($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNatural($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::natural($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert bool|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrBoolean($value, $message = '') - { - null === $value || static::boolean($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allBoolean($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::boolean($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrBoolean($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::boolean($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert scalar|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrScalar($value, $message = '') - { - null === $value || static::scalar($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allScalar($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::scalar($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrScalar($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::scalar($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert object|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrObject($value, $message = '') - { - null === $value || static::object($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allObject($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::object($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrObject($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::object($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert resource|null $value - * - * @param mixed $value - * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrResource($value, $type = null, $message = '') - { - null === $value || static::resource($value, $type, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allResource($value, $type = null, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::resource($entry, $type, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrResource($value, $type = null, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::resource($entry, $type, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert callable|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsCallable($value, $message = '') - { - null === $value || static::isCallable($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsCallable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isCallable($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsCallable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isCallable($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert array|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsArray($value, $message = '') - { - null === $value || static::isArray($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsArray($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isArray($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsArray($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isArray($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable|null $value - * - * @deprecated use "isIterable" or "isInstanceOf" instead - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsTraversable($value, $message = '') - { - null === $value || static::isTraversable($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @deprecated use "isIterable" or "isInstanceOf" instead - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsTraversable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isTraversable($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @deprecated use "isIterable" or "isInstanceOf" instead - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsTraversable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isTraversable($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert array|ArrayAccess|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsArrayAccessible($value, $message = '') - { - null === $value || static::isArrayAccessible($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsArrayAccessible($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isArrayAccessible($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsArrayAccessible($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isArrayAccessible($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert countable|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsCountable($value, $message = '') - { - null === $value || static::isCountable($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsCountable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isCountable($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsCountable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isCountable($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsIterable($value, $message = '') - { - null === $value || static::isIterable($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsIterable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isIterable($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsIterable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isIterable($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert ExpectedType|null $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsInstanceOf($value, $class, $message = '') - { - null === $value || static::isInstanceOf($value, $class, $message); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsInstanceOf($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isInstanceOf($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsInstanceOf($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isInstanceOf($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotInstanceOf($value, $class, $message = '') - { - null === $value || static::notInstanceOf($value, $class, $message); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotInstanceOf($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notInstanceOf($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotInstanceOf($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notInstanceOf($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param mixed $value - * @param array $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsInstanceOfAny($value, $classes, $message = '') - { - null === $value || static::isInstanceOfAny($value, $classes, $message); - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param mixed $value - * @param array $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsInstanceOfAny($value, $classes, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isInstanceOfAny($entry, $classes, $message); - } - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param mixed $value - * @param array $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsInstanceOfAny($value, $classes, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isInstanceOfAny($entry, $classes, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert ExpectedType|class-string|null $value - * - * @param object|string|null $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsAOf($value, $class, $message = '') - { - null === $value || static::isAOf($value, $class, $message); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable> $value - * - * @param iterable $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsAOf($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isAOf($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable|null> $value - * - * @param iterable $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsAOf($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isAOf($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-template UnexpectedType of object - * @psalm-param class-string $class - * - * @param object|string|null $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsNotA($value, $class, $message = '') - { - null === $value || static::isNotA($value, $class, $message); - } - - /** - * @psalm-pure - * @psalm-template UnexpectedType of object - * @psalm-param class-string $class - * - * @param iterable $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsNotA($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isNotA($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-template UnexpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable $value - * @psalm-assert iterable|null> $value - * - * @param iterable $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsNotA($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isNotA($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param object|string|null $value - * @param string[] $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsAnyOf($value, $classes, $message = '') - { - null === $value || static::isAnyOf($value, $classes, $message); - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param iterable $value - * @param string[] $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsAnyOf($value, $classes, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isAnyOf($entry, $classes, $message); - } - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param iterable $value - * @param string[] $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsAnyOf($value, $classes, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isAnyOf($entry, $classes, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert empty $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsEmpty($value, $message = '') - { - null === $value || static::isEmpty($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsEmpty($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::isEmpty($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsEmpty($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::isEmpty($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotEmpty($value, $message = '') - { - null === $value || static::notEmpty($value, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotEmpty($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notEmpty($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotEmpty($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notEmpty($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNull($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::null($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotNull($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notNull($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert true|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrTrue($value, $message = '') - { - null === $value || static::true($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allTrue($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::true($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrTrue($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::true($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert false|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrFalse($value, $message = '') - { - null === $value || static::false($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allFalse($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::false($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrFalse($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::false($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotFalse($value, $message = '') - { - null === $value || static::notFalse($value, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotFalse($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notFalse($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotFalse($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notFalse($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIp($value, $message = '') - { - null === $value || static::ip($value, $message); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIp($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::ip($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIp($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::ip($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIpv4($value, $message = '') - { - null === $value || static::ipv4($value, $message); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIpv4($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::ipv4($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIpv4($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::ipv4($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIpv6($value, $message = '') - { - null === $value || static::ipv6($value, $message); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIpv6($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::ipv6($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIpv6($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::ipv6($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrEmail($value, $message = '') - { - null === $value || static::email($value, $message); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allEmail($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::email($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrEmail($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::email($entry, $message); - } - } - - /** - * @param array|null $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrUniqueValues($values, $message = '') - { - null === $values || static::uniqueValues($values, $message); - } - - /** - * @param iterable $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allUniqueValues($values, $message = '') - { - static::isIterable($values); - - foreach ($values as $entry) { - static::uniqueValues($entry, $message); - } - } - - /** - * @param iterable $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrUniqueValues($values, $message = '') - { - static::isIterable($values); - - foreach ($values as $entry) { - null === $entry || static::uniqueValues($entry, $message); - } - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrEq($value, $expect, $message = '') - { - null === $value || static::eq($value, $expect, $message); - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allEq($value, $expect, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::eq($entry, $expect, $message); - } - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrEq($value, $expect, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::eq($entry, $expect, $message); - } - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotEq($value, $expect, $message = '') - { - null === $value || static::notEq($value, $expect, $message); - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotEq($value, $expect, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notEq($entry, $expect, $message); - } - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotEq($value, $expect, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notEq($entry, $expect, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrSame($value, $expect, $message = '') - { - null === $value || static::same($value, $expect, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allSame($value, $expect, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::same($entry, $expect, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrSame($value, $expect, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::same($entry, $expect, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotSame($value, $expect, $message = '') - { - null === $value || static::notSame($value, $expect, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotSame($value, $expect, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notSame($entry, $expect, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotSame($value, $expect, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notSame($entry, $expect, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrGreaterThan($value, $limit, $message = '') - { - null === $value || static::greaterThan($value, $limit, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allGreaterThan($value, $limit, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::greaterThan($entry, $limit, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrGreaterThan($value, $limit, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::greaterThan($entry, $limit, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrGreaterThanEq($value, $limit, $message = '') - { - null === $value || static::greaterThanEq($value, $limit, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allGreaterThanEq($value, $limit, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::greaterThanEq($entry, $limit, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrGreaterThanEq($value, $limit, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::greaterThanEq($entry, $limit, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLessThan($value, $limit, $message = '') - { - null === $value || static::lessThan($value, $limit, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLessThan($value, $limit, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::lessThan($entry, $limit, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrLessThan($value, $limit, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::lessThan($entry, $limit, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLessThanEq($value, $limit, $message = '') - { - null === $value || static::lessThanEq($value, $limit, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLessThanEq($value, $limit, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::lessThanEq($entry, $limit, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrLessThanEq($value, $limit, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::lessThanEq($entry, $limit, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $min - * @param mixed $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrRange($value, $min, $max, $message = '') - { - null === $value || static::range($value, $min, $max, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $min - * @param mixed $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allRange($value, $min, $max, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::range($entry, $min, $max, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $min - * @param mixed $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrRange($value, $min, $max, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::range($entry, $min, $max, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrOneOf($value, $values, $message = '') - { - null === $value || static::oneOf($value, $values, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allOneOf($value, $values, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::oneOf($entry, $values, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrOneOf($value, $values, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::oneOf($entry, $values, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrInArray($value, $values, $message = '') - { - null === $value || static::inArray($value, $values, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allInArray($value, $values, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::inArray($entry, $values, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrInArray($value, $values, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::inArray($entry, $values, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrContains($value, $subString, $message = '') - { - null === $value || static::contains($value, $subString, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allContains($value, $subString, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::contains($entry, $subString, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrContains($value, $subString, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::contains($entry, $subString, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotContains($value, $subString, $message = '') - { - null === $value || static::notContains($value, $subString, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotContains($value, $subString, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notContains($entry, $subString, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotContains($value, $subString, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notContains($entry, $subString, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotWhitespaceOnly($value, $message = '') - { - null === $value || static::notWhitespaceOnly($value, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotWhitespaceOnly($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notWhitespaceOnly($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotWhitespaceOnly($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notWhitespaceOnly($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrStartsWith($value, $prefix, $message = '') - { - null === $value || static::startsWith($value, $prefix, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allStartsWith($value, $prefix, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::startsWith($entry, $prefix, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrStartsWith($value, $prefix, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::startsWith($entry, $prefix, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotStartsWith($value, $prefix, $message = '') - { - null === $value || static::notStartsWith($value, $prefix, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotStartsWith($value, $prefix, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notStartsWith($entry, $prefix, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotStartsWith($value, $prefix, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notStartsWith($entry, $prefix, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrStartsWithLetter($value, $message = '') - { - null === $value || static::startsWithLetter($value, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allStartsWithLetter($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::startsWithLetter($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrStartsWithLetter($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::startsWithLetter($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrEndsWith($value, $suffix, $message = '') - { - null === $value || static::endsWith($value, $suffix, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allEndsWith($value, $suffix, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::endsWith($entry, $suffix, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrEndsWith($value, $suffix, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::endsWith($entry, $suffix, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotEndsWith($value, $suffix, $message = '') - { - null === $value || static::notEndsWith($value, $suffix, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotEndsWith($value, $suffix, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notEndsWith($entry, $suffix, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotEndsWith($value, $suffix, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notEndsWith($entry, $suffix, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrRegex($value, $pattern, $message = '') - { - null === $value || static::regex($value, $pattern, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allRegex($value, $pattern, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::regex($entry, $pattern, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrRegex($value, $pattern, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::regex($entry, $pattern, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotRegex($value, $pattern, $message = '') - { - null === $value || static::notRegex($value, $pattern, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotRegex($value, $pattern, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::notRegex($entry, $pattern, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrNotRegex($value, $pattern, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::notRegex($entry, $pattern, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrUnicodeLetters($value, $message = '') - { - null === $value || static::unicodeLetters($value, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allUnicodeLetters($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::unicodeLetters($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrUnicodeLetters($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::unicodeLetters($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrAlpha($value, $message = '') - { - null === $value || static::alpha($value, $message); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allAlpha($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::alpha($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrAlpha($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::alpha($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrDigits($value, $message = '') - { - null === $value || static::digits($value, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allDigits($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::digits($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrDigits($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::digits($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrAlnum($value, $message = '') - { - null === $value || static::alnum($value, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allAlnum($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::alnum($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrAlnum($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::alnum($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert lowercase-string|null $value - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLower($value, $message = '') - { - null === $value || static::lower($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLower($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::lower($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrLower($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::lower($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrUpper($value, $message = '') - { - null === $value || static::upper($value, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allUpper($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::upper($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrUpper($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::upper($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param int $length - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLength($value, $length, $message = '') - { - null === $value || static::length($value, $length, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int $length - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLength($value, $length, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::length($entry, $length, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int $length - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrLength($value, $length, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::length($entry, $length, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMinLength($value, $min, $message = '') - { - null === $value || static::minLength($value, $min, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMinLength($value, $min, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::minLength($entry, $min, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrMinLength($value, $min, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::minLength($entry, $min, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMaxLength($value, $max, $message = '') - { - null === $value || static::maxLength($value, $max, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMaxLength($value, $max, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::maxLength($entry, $max, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrMaxLength($value, $max, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::maxLength($entry, $max, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLengthBetween($value, $min, $max, $message = '') - { - null === $value || static::lengthBetween($value, $min, $max, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLengthBetween($value, $min, $max, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::lengthBetween($entry, $min, $max, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrLengthBetween($value, $min, $max, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::lengthBetween($entry, $min, $max, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrFileExists($value, $message = '') - { - null === $value || static::fileExists($value, $message); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allFileExists($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::fileExists($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrFileExists($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::fileExists($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrFile($value, $message = '') - { - null === $value || static::file($value, $message); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allFile($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::file($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrFile($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::file($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrDirectory($value, $message = '') - { - null === $value || static::directory($value, $message); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allDirectory($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::directory($entry, $message); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrDirectory($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::directory($entry, $message); - } - } - - /** - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrReadable($value, $message = '') - { - null === $value || static::readable($value, $message); - } - - /** - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allReadable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::readable($entry, $message); - } - } - - /** - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrReadable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::readable($entry, $message); - } - } - - /** - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrWritable($value, $message = '') - { - null === $value || static::writable($value, $message); - } - - /** - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allWritable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::writable($entry, $message); - } - } - - /** - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrWritable($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::writable($entry, $message); - } - } - - /** - * @psalm-assert class-string|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrClassExists($value, $message = '') - { - null === $value || static::classExists($value, $message); - } - - /** - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allClassExists($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::classExists($entry, $message); - } - } - - /** - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrClassExists($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::classExists($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert class-string|ExpectedType|null $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrSubclassOf($value, $class, $message = '') - { - null === $value || static::subclassOf($value, $class, $message); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable|ExpectedType> $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allSubclassOf($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::subclassOf($entry, $class, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable|ExpectedType|null> $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrSubclassOf($value, $class, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::subclassOf($entry, $class, $message); - } - } - - /** - * @psalm-assert class-string|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrInterfaceExists($value, $message = '') - { - null === $value || static::interfaceExists($value, $message); - } - - /** - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allInterfaceExists($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::interfaceExists($entry, $message); - } - } - - /** - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrInterfaceExists($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::interfaceExists($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $interface - * @psalm-assert class-string|null $value - * - * @param mixed $value - * @param mixed $interface - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrImplementsInterface($value, $interface, $message = '') - { - null === $value || static::implementsInterface($value, $interface, $message); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $interface - * @psalm-assert iterable> $value - * - * @param mixed $value - * @param mixed $interface - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allImplementsInterface($value, $interface, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::implementsInterface($entry, $interface, $message); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $interface - * @psalm-assert iterable|null> $value - * - * @param mixed $value - * @param mixed $interface - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrImplementsInterface($value, $interface, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::implementsInterface($entry, $interface, $message); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object|null $classOrObject - * - * @param string|object|null $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrPropertyExists($classOrObject, $property, $message = '') - { - null === $classOrObject || static::propertyExists($classOrObject, $property, $message); - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allPropertyExists($classOrObject, $property, $message = '') - { - static::isIterable($classOrObject); - - foreach ($classOrObject as $entry) { - static::propertyExists($entry, $property, $message); - } - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrPropertyExists($classOrObject, $property, $message = '') - { - static::isIterable($classOrObject); - - foreach ($classOrObject as $entry) { - null === $entry || static::propertyExists($entry, $property, $message); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object|null $classOrObject - * - * @param string|object|null $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrPropertyNotExists($classOrObject, $property, $message = '') - { - null === $classOrObject || static::propertyNotExists($classOrObject, $property, $message); - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allPropertyNotExists($classOrObject, $property, $message = '') - { - static::isIterable($classOrObject); - - foreach ($classOrObject as $entry) { - static::propertyNotExists($entry, $property, $message); - } - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrPropertyNotExists($classOrObject, $property, $message = '') - { - static::isIterable($classOrObject); - - foreach ($classOrObject as $entry) { - null === $entry || static::propertyNotExists($entry, $property, $message); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object|null $classOrObject - * - * @param string|object|null $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMethodExists($classOrObject, $method, $message = '') - { - null === $classOrObject || static::methodExists($classOrObject, $method, $message); - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMethodExists($classOrObject, $method, $message = '') - { - static::isIterable($classOrObject); - - foreach ($classOrObject as $entry) { - static::methodExists($entry, $method, $message); - } - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrMethodExists($classOrObject, $method, $message = '') - { - static::isIterable($classOrObject); - - foreach ($classOrObject as $entry) { - null === $entry || static::methodExists($entry, $method, $message); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object|null $classOrObject - * - * @param string|object|null $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMethodNotExists($classOrObject, $method, $message = '') - { - null === $classOrObject || static::methodNotExists($classOrObject, $method, $message); - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMethodNotExists($classOrObject, $method, $message = '') - { - static::isIterable($classOrObject); - - foreach ($classOrObject as $entry) { - static::methodNotExists($entry, $method, $message); - } - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrMethodNotExists($classOrObject, $method, $message = '') - { - static::isIterable($classOrObject); - - foreach ($classOrObject as $entry) { - null === $entry || static::methodNotExists($entry, $method, $message); - } - } - - /** - * @psalm-pure - * - * @param array|null $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrKeyExists($array, $key, $message = '') - { - null === $array || static::keyExists($array, $key, $message); - } - - /** - * @psalm-pure - * - * @param iterable $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allKeyExists($array, $key, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::keyExists($entry, $key, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrKeyExists($array, $key, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::keyExists($entry, $key, $message); - } - } - - /** - * @psalm-pure - * - * @param array|null $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrKeyNotExists($array, $key, $message = '') - { - null === $array || static::keyNotExists($array, $key, $message); - } - - /** - * @psalm-pure - * - * @param iterable $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allKeyNotExists($array, $key, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::keyNotExists($entry, $key, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrKeyNotExists($array, $key, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::keyNotExists($entry, $key, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert array-key|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrValidArrayKey($value, $message = '') - { - null === $value || static::validArrayKey($value, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allValidArrayKey($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::validArrayKey($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrValidArrayKey($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::validArrayKey($entry, $message); - } - } - - /** - * @param Countable|array|null $array - * @param int $number - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrCount($array, $number, $message = '') - { - null === $array || static::count($array, $number, $message); - } - - /** - * @param iterable $array - * @param int $number - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allCount($array, $number, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::count($entry, $number, $message); - } - } - - /** - * @param iterable $array - * @param int $number - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrCount($array, $number, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::count($entry, $number, $message); - } - } - - /** - * @param Countable|array|null $array - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMinCount($array, $min, $message = '') - { - null === $array || static::minCount($array, $min, $message); - } - - /** - * @param iterable $array - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMinCount($array, $min, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::minCount($entry, $min, $message); - } - } - - /** - * @param iterable $array - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrMinCount($array, $min, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::minCount($entry, $min, $message); - } - } - - /** - * @param Countable|array|null $array - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMaxCount($array, $max, $message = '') - { - null === $array || static::maxCount($array, $max, $message); - } - - /** - * @param iterable $array - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMaxCount($array, $max, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::maxCount($entry, $max, $message); - } - } - - /** - * @param iterable $array - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrMaxCount($array, $max, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::maxCount($entry, $max, $message); - } - } - - /** - * @param Countable|array|null $array - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrCountBetween($array, $min, $max, $message = '') - { - null === $array || static::countBetween($array, $min, $max, $message); - } - - /** - * @param iterable $array - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allCountBetween($array, $min, $max, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::countBetween($entry, $min, $max, $message); - } - } - - /** - * @param iterable $array - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrCountBetween($array, $min, $max, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::countBetween($entry, $min, $max, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert list|null $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsList($array, $message = '') - { - null === $array || static::isList($array, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsList($array, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::isList($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsList($array, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::isList($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert non-empty-list|null $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsNonEmptyList($array, $message = '') - { - null === $array || static::isNonEmptyList($array, $message); - } - - /** - * @psalm-pure - * @psalm-assert iterable $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsNonEmptyList($array, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::isNonEmptyList($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsNonEmptyList($array, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::isNonEmptyList($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param mixed|array|null $array - * @psalm-assert array|null $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsMap($array, $message = '') - { - null === $array || static::isMap($array, $message); - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param iterable> $array - * @psalm-assert iterable> $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsMap($array, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::isMap($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param iterable|null> $array - * @psalm-assert iterable|null> $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsMap($array, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::isMap($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param mixed|array|null $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsNonEmptyMap($array, $message = '') - { - null === $array || static::isNonEmptyMap($array, $message); - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param iterable> $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsNonEmptyMap($array, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - static::isNonEmptyMap($entry, $message); - } - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param iterable|null> $array - * @psalm-assert iterable|null> $array - * @psalm-assert iterable $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrIsNonEmptyMap($array, $message = '') - { - static::isIterable($array); - - foreach ($array as $entry) { - null === $entry || static::isNonEmptyMap($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrUuid($value, $message = '') - { - null === $value || static::uuid($value, $message); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allUuid($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - static::uuid($entry, $message); - } - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrUuid($value, $message = '') - { - static::isIterable($value); - - foreach ($value as $entry) { - null === $entry || static::uuid($entry, $message); - } - } - - /** - * @psalm-param class-string $class - * - * @param Closure|null $expression - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrThrows($expression, $class = 'Exception', $message = '') - { - null === $expression || static::throws($expression, $class, $message); - } - - /** - * @psalm-param class-string $class - * - * @param iterable $expression - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allThrows($expression, $class = 'Exception', $message = '') - { - static::isIterable($expression); - - foreach ($expression as $entry) { - static::throws($entry, $class, $message); - } - } - - /** - * @psalm-param class-string $class - * - * @param iterable $expression - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNullOrThrows($expression, $class = 'Exception', $message = '') - { - static::isIterable($expression); - - foreach ($expression as $entry) { - null === $entry || static::throws($entry, $class, $message); - } - } -} diff --git a/sources/Core/Authentication/Client/Smtp/Oauth.php b/sources/Core/Authentication/Client/Smtp/Oauth.php deleted file mode 100644 index 3efa0d1fb..000000000 --- a/sources/Core/Authentication/Client/Smtp/Oauth.php +++ /dev/null @@ -1,124 +0,0 @@ -setUsername($config['username']); - } - } - - // Call parent with original arguments - parent::__construct($host, $port, $origConfig); - } - - /** - * @param OAuthClientProviderAbstract $oProvider - * - * @return void - */ - public static function setProvider(OAuthClientProviderAbstract $oProvider) - { - self::$oProvider = $oProvider; - } - - /** - * Perform LOGIN authentication with supplied credentials - * - */ - public function auth() - { - try { - if (empty(self::$oProvider->GetAccessToken())) { - throw new IdentityProviderException('Not prior authentication to OAuth', 255, []); - } elseif (self::$oProvider->GetAccessToken()->hasExpired()) { - self::$oProvider->SetAccessToken(self::$oProvider->GetVendorProvider()->getAccessToken('refresh_token', [ - 'refresh_token' => self::$oProvider->GetAccessToken()->getRefreshToken(), - 'scope' => self::$oProvider->GetScope(), - ])); - } - } - catch (IdentityProviderException $e) { - IssueLog::Error('Failed to get oAuth credentials for outgoing mails for provider '.self::$oProvider::GetVendorName().' '.$e->getMessage(), static::LOG_CHANNEL); - - return false; - } - $sAccessToken = self::$oProvider->GetAccessToken()->getToken(); - - if (empty($sAccessToken)) { - IssueLog::Error('No OAuth token for outgoing mails for provider '.self::$oProvider::GetVendorName(), static::LOG_CHANNEL); - - return false; - } - - $this->_send('AUTH XOAUTH2 '.base64_encode("user=$this->username\1auth=Bearer $sAccessToken\1\1")); - IssueLog::Debug("SMTP Oauth sending AUTH XOAUTH2 user=$this->username auth=Bearer $sAccessToken", static::LOG_CHANNEL); - - try { - while (true) { - $sResponse = $this->_receive(30); - - IssueLog::Debug("SMTP Oauth receiving ".trim($sResponse), static::LOG_CHANNEL); - - if ($sResponse === '+') { - // Send empty client response. - $this->_send(''); - } else { - if (preg_match('/Unauthorized/i', $sResponse) || - preg_match('/Rejected/i', $sResponse) || - preg_match('/^(535|432|454|534|500|530|538|334)/', $sResponse)) { - IssueLog::Error('Unable to authenticate for outgoing mails for provider '.self::$oProvider::GetVendorName()." Error: $sResponse", static::LOG_CHANNEL); - - return false; - } - if (preg_match("/OK /i", $sResponse) || - preg_match('/Accepted/i', $sResponse) || - preg_match('/^235/i', $sResponse)) { - $this->auth = true; - - return true; - } - - } - } - } catch (RuntimeException $e) { - IssueLog::Error('Timeout connection for outgoing mails for provider '.self::$oProvider::GetVendorName(), static::LOG_CHANNEL); - } - return false; - } -} diff --git a/sources/Core/Email/EmailFactory.php b/sources/Core/Email/EmailFactory.php index 48085f987..0f61552c8 100644 --- a/sources/Core/Email/EmailFactory.php +++ b/sources/Core/Email/EmailFactory.php @@ -2,12 +2,10 @@ namespace Combodo\iTop\Core\Email; -use Combodo\iTop\Core\Email\EMailLaminas; - class EmailFactory { public static function GetMailer() { - return EMailLaminas::GetMailer(); + return EMailSymfony::GetMailer(); } } \ No newline at end of file diff --git a/sources/Core/Email/EmailLaminas.php b/sources/Core/Email/EmailSymfony.php similarity index 61% rename from sources/Core/Email/EmailLaminas.php rename to sources/Core/Email/EmailSymfony.php index 4f5cfbd6d..21c961125 100644 --- a/sources/Core/Email/EmailLaminas.php +++ b/sources/Core/Email/EmailSymfony.php @@ -2,7 +2,7 @@ /** * Send an email (abstraction for synchronous/asynchronous modes) * - * @copyright Copyright (C) 2010-2024 Combodo SAS + * @copyright Copyright (C) 2010-2025 Combodo SAS * @license http://opensource.org/licenses/AGPL-3.0 */ @@ -10,6 +10,8 @@ namespace Combodo\iTop\Core\Email; use AsyncSendEmail; use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory; +use Combodo\iTop\Core\Email\Transport\SymfonyFileTransport; +use Combodo\iTop\Core\Email\Transport\SymfonyOAuthTransport; use DOMDocument; use DOMXPath; use EMail; @@ -17,25 +19,22 @@ use Exception; use ExecutionKPI; use InlineImage; use IssueLog; -use Laminas\Mail\Header\ContentType; -use Laminas\Mail\Header\InReplyTo; -use Laminas\Mail\Header\MessageId; -use Laminas\Mail\Message; -use Combodo\iTop\Core\Authentication\Client\Smtp\Oauth; -use Laminas\Mail\Transport\File; -use Laminas\Mail\Transport\FileOptions; -use Laminas\Mail\Transport\Sendmail; -use Laminas\Mail\Transport\Smtp; -use Laminas\Mail\Transport\SmtpOptions; -use Laminas\Mime\Mime; -use Laminas\Mime\Part; use MetaModel; use Pelago\Emogrifier\CssInliner; use Pelago\Emogrifier\HtmlProcessor\CssToAttributeConverter; use Pelago\Emogrifier\HtmlProcessor\HtmlPruner; use Symfony\Component\CssSelector\Exception\ParseException; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; +use Symfony\Component\Mailer\Transport; +use Symfony\Component\Mailer\Mailer; +use Symfony\Component\Mime\Email as SymfonyEmail; +use Symfony\Component\Mime\Part\DataPart; +use Symfony\Component\Mime\Part\Multipart\RelatedPart; +use Symfony\Component\Mime\Part\Multipart\MixedPart; +use Symfony\Component\Mime\Part\Multipart\AlternativePart; +use Symfony\Component\Mime\Part\TextPart; -class EMailLaminas extends Email +class EMailSymfony extends Email { // Serialization formats const ORIGINAL_FORMAT = 1; // Original format, consisting in serializing the whole object, inculding the Swift Mailer's object. @@ -53,8 +52,7 @@ class EMailLaminas extends Email public function __construct() { $this->m_aData = array(); - $this->m_oMessage = new Message(); - $this->m_oMessage->setEncoding('UTF-8'); + $this->m_oMessage = new SymfonyEmail(); $this->InitRecipientFrom(); } @@ -133,28 +131,30 @@ class EMailLaminas extends Email } catch (Exception $e) { $aIssues = array($e->GetMessage()); - return EMAIL_SEND_ERROR; } $aIssues = array(); - return EMAIL_SEND_PENDING; } public static function GetMailer() { - return new EMailLaminas(); + return new EMailSymfony(); } /** + * Send synchronously using symfony/mailer + * * @throws \Exception */ protected function SendSynchronous(&$aIssues, $oLog = null) { - $this->LoadConfig(); $sTransport = self::$m_oConfig->Get('email_transport'); + $oMailer = null; + $oTransport = null; + switch ($sTransport) { case 'SMTP': $sHost = self::$m_oConfig->Get('email_transport_smtp.host'); @@ -164,81 +164,92 @@ class EMailLaminas extends Email $sPassword = self::$m_oConfig->Get('email_transport_smtp.password'); $bVerifyPeer = static::$m_oConfig->Get('email_transport_smtp.verify_peer'); - $oTransport = new Smtp(); - $aOptions = []; - $aConnectionConfig = []; - $aOptions['host'] = $sHost; - $aOptions['port'] = $sPort; + // Build the DSN string + $sDsnUser = $sUserName !== null ? rawurlencode($sUserName) : ''; + $sDsnPassword = ($sPassword !== null && $sPassword !== '') ? ':' . rawurlencode($sPassword) : ''; + $sDsnPort = $sHost . (strlen($sPort) ? ':' . $sPort : ''); + $sDsn = null; - $aConnectionConfig['ssl'] = $sEncryption; - $aConnectionConfig['novalidatecert'] = !$bVerifyPeer; - - if (strlen($sPassword) > 0) { - $aConnectionConfig['username'] = $sUserName; - $aConnectionConfig['password'] = $sPassword; - $aOptions['connection_class'] = 'login'; + if (strtolower($sEncryption) === 'ssl') { + // Implicit TLS (smtps) + $sDsn = sprintf('smtps://%s%s@%s', $sDsnUser, $sDsnPassword, $sDsnPort); } else { - $aOptions['connection_class'] = 'smtp'; + // Regular smtp, can enable starttls via query param + $sEncQuery = ''; + if (strtolower($sEncryption) === 'tls') { + $sEncQuery = '?encryption=starttls'; + } + $sDsn = sprintf('smtp://%s%s@%s%s', $sDsnUser, $sDsnPassword, $sDsnPort, $sEncQuery); } - $aOptions['connection_config'] = $aConnectionConfig; + $oTransport = Transport::fromDsn($sDsn); - $oOptions = new SmtpOptions($aOptions); - $oTransport->setOptions($oOptions); + // Handle peer verification + $oStream = $oTransport->getStream(); + $aOptions= $oStream->getStreamOptions(); + if (!$bVerifyPeer && array_key_exists('ssl', $aOptions)) { + // Disable verification + $aOptions['ssl']['verify_peer'] = false; + $aOptions['ssl']['verify_peer_name'] = false; + $aOptions['ssl']['allow_self_signed'] = true; + } + $oStream->setStreamOptions($aOptions); + + $oMailer = new Mailer($oTransport); break; case 'SMTP_OAuth': + // Use custom SMTP transport $sHost = self::$m_oConfig->Get('email_transport_smtp.host'); $sPort = self::$m_oConfig->Get('email_transport_smtp.port'); $sEncryption = self::$m_oConfig->Get('email_transport_smtp.encryption'); $sUserName = self::$m_oConfig->Get('email_transport_smtp.username'); - $oTransport = new Smtp(); - $aOptions = [ - 'host' => $sHost, - 'port' => $sPort, - 'connection_class' => 'Laminas\Mail\Protocol\Smtp\Auth\Oauth', - 'connection_config' => [ - 'ssl' => $sEncryption, - ], - ]; - if (strlen($sUserName) > 0) { - $aOptions['connection_config']['username'] = $sUserName; - } - $oOptions = new SmtpOptions($aOptions); - $oTransport->setOptions($oOptions); - - Oauth::setProvider(OAuthClientProviderFactory::GetProviderForSMTP()); + $oTransport = new SymfonyOAuthTransport([ + 'host' => $sHost, + 'port' => $sPort, + 'encryption' => $sEncryption, + 'username' => $sUserName, + ]); + $oMailer = new Mailer($oTransport); + SymfonyOAuthTransport::setProvider(OAuthClientProviderFactory::GetProviderForSMTP()); break; case 'Null': - $oTransport = new Smtp(); + // Use a dummy transport + $oTransport = Transport::fromDsn('null://null'); + $oMailer = new Mailer($oTransport); break; case 'LogFile': - $oTransport = new File(); - $aOptions = new FileOptions([ - 'path' => APPROOT.'log/', - 'callback' => function() { return 'mail.log'; } - ]); - $oTransport->setOptions($aOptions); + // Use a custom transport that writes to a log file + // Note: the log file is not rotated, so this should be used for debugging + $oTransport = new SymfonyFileTransport(APPROOT . 'log/', 'mail.log'); + $oMailer = new Mailer($oTransport); break; case 'PHPMail': default: - $oTransport = new Sendmail(); + // Use sendmail transport + $oTransport = Transport::fromDsn('sendmail://default'); + $oMailer = new Mailer($oTransport); } $oKPI = new ExecutionKPI(); + try { - $oTransport->send($this->m_oMessage); + if ($oMailer === null || $oTransport === null) { + throw new \RuntimeException('No mailer transport configured.'); + } + + $oMailer->send($this->m_oMessage); $aIssues = array(); $oKPI->ComputeStats('Email Sent', 'Succeded'); return EMAIL_SEND_OK; } - catch (Laminas\Mail\Transport\Exception\RuntimeException $e) { + catch (TransportExceptionInterface $e) { IssueLog::Warning('Email sending failed: '.$e->getMessage()); $aIssues = array($e->getMessage()); $oKPI->ComputeStats('Email Sent', 'Error received'); @@ -266,14 +277,13 @@ class EMailLaminas extends Email { $oDOMDoc = new DOMDocument(); $oDOMDoc->preserveWhiteSpace = true; - @$oDOMDoc->loadHTML(''.$sBody); // For loading HTML chunks where the character set is not specified + @$oDOMDoc->loadHTML(''.$sBody); $oXPath = new DOMXPath($oDOMDoc); $sXPath = '//img[@'.InlineImage::DOM_ATTR_ID.']'; $oImagesList = $oXPath->query($sXPath); - $oImagesContent = new \Laminas\Mime\Message(); $aImagesParts = []; - if ($oImagesList->length != 0) { + if ($oImagesList->length !== 0) { foreach ($oImagesList as $oImg) { $iAttId = $oImg->getAttribute(InlineImage::DOM_ATTR_ID); $oAttachment = MetaModel::GetObject('InlineImage', $iAttId, false, true /* Allow All Data */); @@ -287,19 +297,14 @@ class EMailLaminas extends Email } $oDoc = $oAttachment->Get('contents'); + // CID expects to be unique and to contain a @, see RFC 2392 + $sCid = uniqid('', true).'@openitop.org'; - $sCid = uniqid('', true); + $oPart = new DataPart($oDoc->GetData(), $oDoc->GetFileName(), $oDoc->GetMimeType()); + $oPart->setContentId($sCid)->asInline(); - $oNewAttachment = new Part($oDoc->GetData()); - $oNewAttachment->id = $sCid; - $oNewAttachment->type = $oDoc->GetMimeType(); - $oNewAttachment->filename = $oDoc->GetFileName(); - $oNewAttachment->disposition = Mime::DISPOSITION_INLINE; - $oNewAttachment->encoding = Mime::ENCODING_BASE64; - - $oImagesContent->addPart($oNewAttachment); + $aImagesParts[] = $oPart; $oImg->setAttribute('src', 'cid:'.$sCid); - $aImagesParts[] = $oNewAttachment; } } } @@ -311,17 +316,6 @@ class EMailLaminas extends Email /** * Sends an e-mail. * - * @param string[] $aIssues Array to add any potentially encountered issues to. - * @param int|bool $iSyncAsync Specify whether the e-mail will be sent per default configuration, or whether there will be a forced (a)synchronous sending. One of Email::ENUM_SEND_* constants. To support legacy, it also allows a boolean (true = send synchronous). - * @param Object|null $oLog Log - * - * @details By default, the send method will respect the preference to send e-mails in an (a)synchronous way as defined in the iTop configuration by the administrator. - * In some use cases, it may be necessary to override this behavior. For example, for some tests it may be best if e-mails are always sent instantly (synchronous). - * Asynchronous may be preferred when sending a lot of bulk e-mails at once, to avoid hitting rate limits of e-mail providers (e.g. customer survey extension). - * - * @since 3.2.0 Previously, $iSyncAsync was a boolean ($bForceSynchronous) and this method only allowed to forcefully send e-mails synchronously even when the default was asynchronous. - * - * @return */ public function Send(&$aIssues, $iSyncAsync = Email::ENUM_SEND_DEFAULT, $oLog = null) { @@ -330,24 +324,16 @@ class EMailLaminas extends Email $this->SetRecipientFrom($this->m_aData['to']); } - // In previous iTop versions, $iSyncAsync was $bForceSynchronous. To retain backward compatibility, this check is in place. if($iSyncAsync === true) { - // This legacy mode forces synchronous sending, ignoring whatever default was configured. return $this->SendSynchronous($aIssues, $oLog); } else { - switch($iSyncAsync) { - case Email::ENUM_SEND_FORCE_SYNCHRONOUS: return $this->SendSynchronous($aIssues, $oLog); - case Email::ENUM_SEND_FORCE_ASYNCHRONOUS: return $this->SendAsynchronous($aIssues, $oLog); - case Email::ENUM_SEND_DEFAULT: default: - - // Default behavior. $oConfig = $this->LoadConfig(); $bConfigASYNC = $oConfig->Get('email_asynchronous'); if($bConfigASYNC) { @@ -359,6 +345,9 @@ class EMailLaminas extends Email } } + /** + * Add a header line + */ public function AddToHeader($sKey, $sValue) { if (!array_key_exists('headers', $this->m_aData)) { @@ -367,8 +356,7 @@ class EMailLaminas extends Email $this->m_aData['headers'][$sKey] = $sValue; if (strlen($sValue) > 0) { - $oHeaders = $this->m_oMessage->getHeaders(); - $oHeaders->addHeaderLine($sKey, $sValue); + $this->m_oMessage->getHeaders()->addTextHeader($sKey, $sValue); } } @@ -380,7 +368,7 @@ class EMailLaminas extends Email // so let's remove the angle brackets if present, for historical reasons $sId = str_replace(array('<', '>'), '', $sId); - $this->m_oMessage->getHeaders()->addHeader((new MessageId())->setId($sId)); + $this->m_oMessage->getHeaders()->addIdHeader('Message-ID', $sId); } public function SetReferences($sReferences) @@ -388,86 +376,77 @@ class EMailLaminas extends Email $this->AddToHeader('References', $sReferences); } - /** - * Set the "In-Reply-To" header to allow emails to group as a conversation in modern mail clients (GMail, Outlook 2016+, ...) - * - * @link https://en.wikipedia.org/wiki/Email#Header_fields - * - * @param string $sMessageId - * - * @since 3.0.1 N°4849 - */ public function SetInReplyTo(string $sMessageId) { - // Note: Laminas will add the angle brackets for you - // so let's remove the angle brackets if present, for historical reasons + // Note: Symfony will add the angle brackets + // let's remove the angle brackets if present, for historical reasons $sId = str_replace(array('<', '>'), '', $sMessageId); + $this->m_aData['in_reply_to'] = '<' . $sId . '>'; - $this->m_oMessage->getHeaders()->addHeader((new InReplyTo())->setIds([$sId])); + $this->m_oMessage->getHeaders()->addTextHeader('In-Reply-To', '<' . $sId . '>'); } /** * Set current Email body and process inline images. - * - * @param $sBody - * @param string $sMimeType - * @param null $sCustomStyles - * - * @return void - * @throws \ArchivedObjectException - * @throws \CoreException - * @throws \Symfony\Component\CssSelector\Exception\ParseException */ - public function SetBody($sBody, $sMimeType = Mime::TYPE_HTML, $sCustomStyles = null) + public function SetBody($sBody, $sMimeType = 'text/html', $sCustomStyles = null) { - $oBody = new \Laminas\Mime\Message(); - $aAdditionalParts = []; - - if ($sMimeType === Mime::TYPE_HTML) { + // Inline CSS if needed + if ($sMimeType === 'text/html') { $sBody = static::InlineCssIntoBodyContent($sBody, $sCustomStyles); } + $this->m_aData['body'] = array('body' => $sBody, 'mimeType' => $sMimeType); - // We don't want these modifications in m_aData['body'], otherwise it'll ruin asynchronous mail as they go through this method twice - if ($sMimeType === Mime::TYPE_HTML) { + $oTextPart = new TextPart(strip_tags($sBody), 'utf-8', 'plain', 'base64'); + + // Embed inline images and store them in attachments (so BuildSymfonyMessageFromInternal can pick them) + if ($sMimeType === 'text/html') { $aAdditionalParts = $this->EmbedInlineImages($sBody); + $oHtmlPart = new TextPart($sBody, 'utf-8', 'html', 'base64'); + $oAlternativePart = new AlternativePart($oHtmlPart, $oTextPart); + // Default root part is the HTML body + $oRootPart = $oAlternativePart; + + if(count($aAdditionalParts) > 0) { + $aRelatedParts = array_merge([$oAlternativePart], $aAdditionalParts); + $oRootPart = new RelatedPart(...$aRelatedParts); + } + } + else { + // Default root part is the text body + $oRootPart = $oTextPart; } - // Add body content to as a new part - $oNewPart = new Part($sBody); - $oNewPart->encoding = Mime::ENCODING_BASE64; - $oNewPart->type = $sMimeType; - $oNewPart->charset = 'UTF-8'; - $oBody->addPart($oNewPart); + $this->m_oMessage->setBody($oRootPart); + } - // Add additional images as new body parts - foreach ($aAdditionalParts as $oAdditionalPart) { - $oBody->addPart($oAdditionalPart); + protected function GetMimeSubtype($sMimeType, $sDefault = 'html') + { + $sMimeSubtype = ''; + if (strpos($sMimeType, '/') !== false) { + $aParts = explode('/', $sMimeType); + if (count($aParts) > 1) { + $sMimeSubtype = $aParts[1]; + } } - - $this->m_oMessage->setBody($oBody); + return $sMimeSubtype !== '' ?? $sDefault; } /** * Add a new part to the existing body - * - * @param $sText - * @param string $sMimeType - * - * @return void */ - public function AddPart($sText, $sMimeType = Mime::TYPE_HTML) + public function AddPart($sText, $sMimeType = 'text/html') { + $sMimeSubtype = $this->GetMimeSubtype($sMimeType); + if (!array_key_exists('parts', $this->m_aData)) { $this->m_aData['parts'] = array(); } $this->m_aData['parts'][] = array('text' => $sText, 'mimeType' => $sMimeType); - $oNewPart = new Part($sText); - $oNewPart->encoding = Mime::ENCODING_BASE64; - $oNewPart->type = $sMimeType; - // setBody called only to refresh Content-Type to multipart/mixed - $this->m_oMessage->setBody($this->m_oMessage->getBody()->addPart($oNewPart)); + $oNewPart = new TextPart($sText, $sMimeType, $sMimeSubtype, 'base64'); + $this->m_oMessage->addPart($oNewPart); } public function AddAttachment($data, $sFileName, $sMimeType) @@ -476,20 +455,27 @@ class EMailLaminas extends Email $this->m_aData['attachments'] = array(); } $this->m_aData['attachments'][] = array('data' => base64_encode($data), 'filename' => $sFileName, 'mimeType' => $sMimeType); - $oNewAttachment = new Part($data); - $oNewAttachment->type = $sMimeType; - $oNewAttachment->filename = $sFileName; - $oNewAttachment->disposition = Mime::DISPOSITION_ATTACHMENT; - $oNewAttachment->encoding = Mime::ENCODING_BASE64; - // setBody called only to refresh Content-Type to multipart/mixed - $this->m_oMessage->setBody($this->m_oMessage->getBody()->addPart($oNewAttachment)); + $oBody = $this->m_oMessage->getBody(); + + $oRootPart = $oBody; + $aAttachmentPart = new DataPart($data, $sFileName, $sMimeType, 'base64'); + if( $oBody instanceof MixedPart) { + $aCurrentParts = $oBody->getParts(); + $aCurrentParts[] = $aAttachmentPart; + $oRootPart = new MixedPart(...$aCurrentParts); + } + else { + $oRootPart = new MixedPart($oBody, $aAttachmentPart); + } + + $this->m_oMessage->setBody($oRootPart); } public function SetSubject($sSubject) { $this->m_aData['subject'] = $sSubject; - $this->m_oMessage->setSubject($sSubject); + $this->m_oMessage->subject($sSubject); } public function GetSubject() @@ -499,7 +485,6 @@ class EMailLaminas extends Email /** * Helper to transform and sanitize addresses - * - get rid of empty addresses */ protected function AddressStringToArray($sAddressCSVList) { @@ -510,7 +495,6 @@ class EMailLaminas extends Email $aAddresses[] = $sAddress; } } - return $aAddresses; } @@ -519,34 +503,30 @@ class EMailLaminas extends Email $this->m_aData['to'] = $sAddress; if (!empty($sAddress)) { $aAddresses = $this->AddressStringToArray($sAddress); - $this->m_oMessage->setTo($aAddresses); + $this->m_oMessage->to(...$aAddresses); } } public function GetRecipientTO($bAsString = false) { $aRes = $this->m_oMessage->getTo(); - if ($aRes === null || $aRes->count() === 0) { - // There is no "To" header field - $aRes = array(); - } + if ($bAsString) { $aStrings = array(); foreach ($aRes as $oEmail) { $sName = $oEmail->getName(); - $sEmail = $oEmail->getEmail(); - if (is_null($sName)) { + $sEmail = $oEmail->getAddress(); + if (empty($sName)) { $aStrings[] = $sEmail; } else { $sName = str_replace(array('<', '>'), '', $sName); $aStrings[] = "$sName <$sEmail>"; } } - return implode(', ', $aStrings); - } else { - return $aRes; } + + return $aRes; } public function SetRecipientCC($sAddress) @@ -554,7 +534,7 @@ class EMailLaminas extends Email $this->m_aData['cc'] = $sAddress; if (!empty($sAddress)) { $aAddresses = $this->AddressStringToArray($sAddress); - $this->m_oMessage->setCc($aAddresses); + $this->m_oMessage->cc(...$aAddresses); } } @@ -563,7 +543,7 @@ class EMailLaminas extends Email $this->m_aData['bcc'] = $sAddress; if (!empty($sAddress)) { $aAddresses = $this->AddressStringToArray($sAddress); - $this->m_oMessage->setBcc($aAddresses); + $this->m_oMessage->bcc(...$aAddresses); } } @@ -571,9 +551,9 @@ class EMailLaminas extends Email { $this->m_aData['from'] = array('address' => $sAddress, 'label' => $sLabel); if ($sLabel != '') { - $this->m_oMessage->setFrom(array($sAddress => $sLabel)); + $this->m_oMessage->from(sprintf('%s <%s>', $sLabel, $sAddress)); } else if (!empty($sAddress)) { - $this->m_oMessage->setFrom($sAddress); + $this->m_oMessage->from($sAddress); } } @@ -581,9 +561,9 @@ class EMailLaminas extends Email { $this->m_aData['reply_to'] = array('address' => $sAddress, 'label' => $sLabel); if ($sLabel != '') { - $this->m_oMessage->setReplyTo(array($sAddress => $sLabel)); + $this->m_oMessage->replyTo(sprintf('%s <%s>', $sLabel, $sAddress)); } else if (!empty($sAddress)) { - $this->m_oMessage->setReplyTo($sAddress); + $this->m_oMessage->replyTo($sAddress); } } @@ -592,7 +572,7 @@ class EMailLaminas extends Email * @param string $sCustomStyles * * @return string - * @throws \Symfony\Component\CssSelector\Exception\ParseException + * @throws ParseException * @noinspection PhpUnnecessaryLocalVariableInspection */ protected static function InlineCssIntoBodyContent($sBody, $sCustomStyles): string @@ -603,9 +583,8 @@ class EMailLaminas extends Email $oDomDocument = CssInliner::fromHtml($sBody)->inlineCss($sCustomStyles)->getDomDocument(); HtmlPruner::fromDomDocument($oDomDocument)->removeElementsWithDisplayNone(); - $sBody = CssToAttributeConverter::fromDomDocument($oDomDocument)->convertCssToVisualAttributes()->render(); // Adds html/body tags if not already present + $sBody = CssToAttributeConverter::fromDomDocument($oDomDocument)->convertCssToVisualAttributes()->render(); return $sBody; } - -} +} \ No newline at end of file diff --git a/sources/Core/Email/Transport/SymfonyFileTransport.php b/sources/Core/Email/Transport/SymfonyFileTransport.php new file mode 100644 index 000000000..6f007a1bd --- /dev/null +++ b/sources/Core/Email/Transport/SymfonyFileTransport.php @@ -0,0 +1,63 @@ +sDir = rtrim($sLogDir ?? APPROOT . 'log/', DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + $this->sFilename = $sFilename; + } + + /** + * Write the message to the file. + * + * @param SentMessage $message + * + * @throws \RuntimeException + */ + protected function doSend(SentMessage $message): void + { + // Ensure directory exists + if (!is_dir($this->sDir) && !mkdir($concurrentDirectory = $this->sDir, 0755, true) && !is_dir($concurrentDirectory)) { + throw new \RuntimeException("Unable to create log directory: {$this->sDir}"); + } + + $sPath = $this->sDir.$this->sFilename; + + // Build an entry header to separate messages + $sEntry = "=== ".date('c')." ===\n"; + + // Get the raw message + $oRawMessage = $message->getOriginalMessage(); + + if (is_object($oRawMessage) && method_exists($oRawMessage, 'toString')) { + $sEntry .= $oRawMessage->toString(); + } + + // Write using LOCK_EX to avoid race conditions + if (@file_put_contents($sPath, $sEntry, FILE_APPEND | LOCK_EX) === false) { + throw new \RuntimeException("Unable to write email entry to log file: {$sPath}"); + } + } + + public function __toString(): string + { + return 'logfile'; + } +} + diff --git a/sources/Core/Email/Transport/SymfonyOAuthTransport.php b/sources/Core/Email/Transport/SymfonyOAuthTransport.php new file mode 100644 index 000000000..553bcb590 --- /dev/null +++ b/sources/Core/Email/Transport/SymfonyOAuthTransport.php @@ -0,0 +1,142 @@ +setUsername($sUsername); + } + + // Make XOAUTH2 be attempted first, then LOGIN/PLAIN as fallback. + $this->setAuthenticators([ + new XOAuth2Authenticator(), + new LoginAuthenticator(), + new PlainAuthenticator(), + ]); + } + + public static function setProvider(OAuthClientProviderAbstract $oProvider): void + { + self::$oProvider = $oProvider; + } + + /** + * Fetch the provider if not explicitly set + */ + protected function getProvider(): OAuthClientProviderAbstract + { + if (self::$oProvider === null) { + self::$oProvider = OAuthClientProviderFactory::GetProviderForSMTP(); + } + + return self::$oProvider; + } + + /** + * Ensure we have a fresh access token and set it as the current SMTP password* + * + * @throws IdentityProviderException + */ + protected function ensureOAuthTokenIsReady(): void + { + $oProvider = $this->getProvider(); + + try { + $oAccessToken = $oProvider->GetAccessToken(); + } + catch (\Throwable $e) { + IssueLog::Error('Failed to get OAuth provider access token: '.$e->getMessage(), 'OAuth'); + throw new TransportException('Failed to obtain OAuth access token for SMTP', 0, $e); + } + + if ($oAccessToken === null) { + throw new IdentityProviderException('Not prior authentication to OAuth', 255, []); + } + elseif ($oAccessToken->hasExpired()) { + self::$oProvider->SetAccessToken(self::$oProvider->GetVendorProvider()->getAccessToken('refresh_token', [ + 'refresh_token' => $oAccessToken->getRefreshToken(), + 'scope' => self::$oProvider->GetScope(), + ])); + } + + $sAccessToken = $oAccessToken->getToken(); + if (empty($sAccessToken)) { + IssueLog::Error('OAuth access token is empty for outgoing mails.', 'OAuth'); + throw new TransportException('OAuth access token is empty.'); + } + + // Set the token as the SMTP "password" as Symfony's XOAuth2Authenticator expects + $this->setPassword($sAccessToken); + } + + /** + * Override send hook so we can refresh the token just before + */ + protected function doSend(SentMessage $message): void + { + // Ensure a fresh token is available and set as SMTP password + try { + $this->ensureOAuthTokenIsReady(); + } + catch (IdentityProviderException $e) { + IssueLog::Error('Failed to get SMTP oAuth credentials for incoming mails for provider '.self::$oProvider::GetVendorName(), static::LOG_CHANNEL, [ + 'exception.message' => $e->getMessage(), + 'exception.stack' => $e->getTraceAsString(), + ]); + } + + $sUsername = $this->getUsername(); + $sAccessToken = $this->getPassword(); + + // Let the normal EsmtpTransport flow continue + IssueLog::Debug("SMTP OAuth trying to login in with user=$sUsername token=$sAccessToken", static::LOG_CHANNEL); + parent::doSend($message); + } +} diff --git a/sources/alias.php b/sources/alias.php index b0a9e22c4..b38127e45 100644 --- a/sources/alias.php +++ b/sources/alias.php @@ -10,8 +10,9 @@ class_alias(\Combodo\iTop\Application\UI\Hook\iKeyboardShortcut::class, 'iKeyboa class_alias(\Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableConfig\DataTableConfig::class, 'DataTableConfig'); class_alias(\Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory::class, 'Combodo\\iTop\\Application\\UI\\Base\\Component\\Input\\SelectUIBlockFactory'); class_alias(\Combodo\iTop\Application\UI\Base\Layout\ActivityPanel\CaseLogEntryForm\CaseLogEntryFormFactory::class, 'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryFormFactory\\CaseLogEntryFormFactory'); -class_alias(\Combodo\iTop\Core\Authentication\Client\Smtp\Oauth::class, 'Laminas\\Mail\\Protocol\\Smtp\\Auth\\Oauth'); -class_alias(\Combodo\iTop\Core\Email\EMailLaminas::class, 'EMailLaminas'); +class_alias(\Combodo\iTop\Core\Email\EMailSymfony::class, 'EMailSymfony'); +class_alias(\Combodo\iTop\Core\Email\Transport\SymfonyFileTransport::class, 'SymfonyFileTransport'); +class_alias(\Combodo\iTop\Core\Email\Transport\SymfonyOAuthTransport::class, 'SymfonyOAuthTransport'); class_alias(\Combodo\iTop\Application\WebPage\AjaxPage::class, 'AjaxPage'); class_alias(\Combodo\iTop\Application\WebPage\CaptureWebPage::class, 'CaptureWebPage'); class_alias(\Combodo\iTop\Application\WebPage\CLILikeWebPage::class, 'CLILikeWebPage'); diff --git a/tests/php-unit-tests/unitary-tests/core/EMailTest.php b/tests/php-unit-tests/unitary-tests/core/EMailTest.php index 1d9d9c133..8df00f299 100644 --- a/tests/php-unit-tests/unitary-tests/core/EMailTest.php +++ b/tests/php-unit-tests/unitary-tests/core/EMailTest.php @@ -39,7 +39,7 @@ class EMailTest extends ItopTestCase { // Check if our charset is correctly set // We know this file may be used by other future test, but as we can't configure output filename, it is what it is $sEmailContent = file_get_contents(APPROOT.'log/mail.log'); - $this->assertStringContainsString('charset="UTF-8"', $sEmailContent); + $this->assertStringContainsStringIgnoringCase('charset=UTF-8', $sEmailContent); // Set our previous email transport value back, so it doesn't affect other tests $oConfig->Set('email_transport', $sCurrentEmailTransport); @@ -78,7 +78,7 @@ class EMailTest extends ItopTestCase { // Check if our charset is correctly set // We know this file may be used by other future test, but as we can't configure output filename, it is what it is $sEmailContent = file_get_contents(APPROOT.'log/mail.log'); - $this->assertStringContainsString('Content-Type: text/plain; charset=UTF-8', $sEmailContent); + $this->assertStringContainsStringIgnoringCase('Content-Type: text/plain; charset=UTF-8', $sEmailContent); // Set our previous email transport value back, so it doesn't affect other tests $oConfig->Set('email_transport', $sCurrentEmailTransport); diff --git a/tests/php-unit-tests/unitary-tests/sources/core/Email/EmailLaminasTest.php b/tests/php-unit-tests/unitary-tests/sources/core/Email/EmailSymfonyTest.php similarity index 96% rename from tests/php-unit-tests/unitary-tests/sources/core/Email/EmailLaminasTest.php rename to tests/php-unit-tests/unitary-tests/sources/core/Email/EmailSymfonyTest.php index 52a525746..bd8c19797 100644 --- a/tests/php-unit-tests/unitary-tests/sources/core/Email/EmailLaminasTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/core/Email/EmailSymfonyTest.php @@ -2,7 +2,7 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase; -class EmailLaminasTest extends ItopTestCase +class EmailSymfonyTest extends ItopTestCase { public function testInlineCssIntoBodyContent(): void { @@ -131,7 +131,7 @@ CSS; HTML; $sExpectedBody .= "\n"; // Emogriffer is always adding latest line feed, adding it in expected content ! - $sActualBody = $this->InvokeNonPublicStaticMethod(EMailLaminas::class, 'InlineCssIntoBodyContent', [$sInputBody, $sInputCss]); + $sActualBody = $this->InvokeNonPublicStaticMethod(EMailSymfony::class, 'InlineCssIntoBodyContent', [$sInputBody, $sInputCss]); $this->assertSame($sExpectedBody, $sActualBody); }